-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Summary
When using pulumiverse-talos (versions 0.5.x and 0.6.x), there is a persistent validation failure when passing machine_secrets generated by the talos:machine:Secrets resource directly into the talos:machine:getConfiguration invoke/function. The validation fails claiming required attributes are missing, even when using consistent talos_version settings.
This appears to be caused by two issues:
- Missing Fields: Certain fields required by
getConfiguration(e.g.,bootstrap_token,secretbox_encryption_secret) are not generated bySecretsfor newer Talos versions (v1.11.5). - Casing Mismatch: The Python SDK generates snake_case keys (e.g.,
k8s_serviceaccount), but the provider's validation logic seemingly expects camelCase keys (e.g.,k8sServiceAccount) for nested structures likecerts, causing it to reject valid secrets objects.
Environment
- Provider Version:
pulumiverse-talosv0.5.2 and v0.6.1 - Pulumi SDK: Python
- Talos Version: v1.11.5 (also tested with v1.9.0)
Steps to Reproduce
- Create a
talos:machine:Secretsresource. - Pass the
machine_secretsoutput from that resource intotalos:machine:get_configuration_output. - Run
pulumi up.
Minimal Code Example (Python)
import pulumi
import pulumiverse_talos as talos
# 1. Generate secrets (Explicit version to match config)
secrets = talos.machine.Secrets("secrets", talos_version="v1.11.5")
# 2. Generate config using those secrets
# This is expected to fail with "Missing Configuration" errors
config = talos.machine.get_configuration_output(
cluster_name="test-cluster",
machine_type="controlplane",
cluster_endpoint="https://1.2.3.4:6443",
machine_secrets=secrets.machine_secrets,
talos_version="v1.11.5"
)Observed Errors
The pulumi up execution fails with "Missing Configuration for Required Attribute" errors from the provider validator. We observed a sequence of missing keys:
bootstrap_token: Even when usingv1.11.5(where this is deprecated), validation often requires it.- Error:
[AttributeName("machine_secrets").AttributeName("secrets").AttributeName("bootstrap_token")] Missing Configuration...
- Error:
secretbox_encryption_secret: Missing from generated secrets.k8s_aggregator: Missing fromcerts.k8s_serviceaccount: Present incerts(snake_case) but rejected by validation.
Debugging Findings
I inspected the secrets.machine_secrets dictionary during runtime.
- Missing Fields:
bootstrap_tokenandsecretbox_encryption_secretwere absent from the dictionary generated bySecrets(talos_version="v1.11.5"). - Casing Mismatch: For certificates like
k8s_serviceaccount, the key existed in the dictionary ask8s_serviceaccount(snake_case). However, the validation failed with "Missing Configuration".- Fix: Manually injecting the camelCase alias
k8sServiceAccountpointing to the same value resolved the error. - This suggests the Python SDK produces snake_case keys, but the underlying Go provider/Bridge expects the wire-format camelCase keys for nested structures in validation.
- Fix: Manually injecting the camelCase alias
Workaround
I got my test cluster to deploy by implementing a manual patching function to inject missing legacy fields and alias existing fields to camelCase:
def patch_secrets(secrets):
# Backfill missing legacy tokens
if not secrets['secrets'].get('bootstrap_token'):
secrets['secrets']['bootstrap_token'] = 'dummy...'
# Backfill missing encryption keys
if not secrets['secrets'].get('secretbox_encryption_secret'):
secrets['secrets']['secretbox_encryption_secret'] = 'dummy...'
# Fix Casing for Certs
# Even if 'k8s_serviceaccount' exists, provider demands 'k8sServiceAccount'
c = secrets['certs']
# Inject both snake_case (if missing) and camelCase aliases
if c.get('k8s_serviceaccount'):
c['k8sServiceAccount'] = c['k8s_serviceaccount']
# Inject k8s_aggregator aliases/dummy
dummy_cert = 'dummy...'
agg_val = c.get('k8s_aggregator') or dummy_cert
c['k8s_aggregator'] = agg_val
c['k8sAggregator'] = agg_val
return secrets
patched_secrets = secrets.machine_secrets.apply(patch_secrets)Expected Behavior
Secretsresource should generate all fields required bygetConfigurationfor the sametalos_version.- The Provider/SDK Bridge should automatically handle case conversion (snake_case to camelCase) for nested maps like
machine_secrets, or the generated Output should already match the expected schema.