Skip to content

TalosConfigTemplate is immutable but applied on every reconcile, so machine-config changes never propagate #3515

Description

@mattia-eleuteri

What happened

TalosConfigTemplate has an immutable .spec (enforced by the vtalosconfigtemplate.cluster.x-k8s.io
webhook), but packages/apps/kubernetes/templates/talos/talos-reconcile-job.yaml applies it with
kubectl apply on every reconcile. As a result, once the template exists, no change to the rendered
Talos machine config can ever reach it
. The apply is rejected server-side:

admission webhook "vtalosconfigtemplate.cluster.x-k8s.io" denied the request:
TalosConfigTemplate.Spec is immutable

This is silent: the Job does not surface it as a distinct error, and the kubernetes-* HelmRelease stays Ready.

Why it matters

Anything rendered into the machine config is frozen at first creation. Concretely, we hit this with
machine.network.searchDomains: our management cluster domain was misconfigured, we corrected
networking.clusterDomain, the chart then rendered the correct searchDomains, and the template kept the
stale value forever
. The same applies to certSANs, machine.registries, nameservers, and any future
machine-config field.

The workaround is to delete + create the TalosConfigTemplate by hand for every tenant cluster after every
platform upgrade, which does not scale and is easy to forget.

Reproduce

  1. Create a tenant Kubernetes cluster and let the workers roll (v1.6.0, Talos workers).
  2. Change any platform value that feeds the machine config, e.g. networking.clusterDomain.
  3. Let the kubernetes-* HelmRelease upgrade and talos-reconcile run.
  4. kubectl -n <tenant-ns> get talosconfigtemplate <cluster>-<group> -o yaml still shows the old value.

Suggested fix

Name the TalosConfigTemplate with a hash of its rendered content, the way
KubevirtMachineTemplate already is in the same chart, and point MachineDeployment.spec.template.spec.bootstrap.configRef
at the hashed name. A content change then creates a new template instead of attempting a rejected mutation,
and CAPI rolls the machines onto it, which is the desired behaviour anyway.

Alternatively, have talos-reconcile detect a content drift and perform the delete/create itself, but the hashed
name is the idiomatic CAPI pattern and avoids a destructive step.

Environment

Cozystack v1.6.0 (packages digest sha256:bf682087…), Talos v1.13.6 workers, Kubernetes v1.34.3 management.

Activity

  1. dosubot commented on Aug 3, 2026

    @dosubot

    Good catch — this is a real gap. The code confirms the asymmetry you described:

    KubevirtMachineTemplate already uses content-hashed naming in cluster.yaml — it computes a sha256sum | trunc 6 of the rendered spec and appends it to the resource name (<release>-<group>-<hash>), so any spec change creates a new object and CAPI rolls the machines [1].

    TalosConfigTemplate, by contrast, uses a stable name ${RELEASE}-${GROUP_NAME} with no hash [2]. The Job's own comment explains this was intentional — "an unchanged render re-applies a byte-identical TCT — a CAPI no-op that never rolls existing workers" [3] — but it doesn't account for the case where the rendered content actually does change, which hits the immutable-spec webhook exactly as you describe.

    The MachineDeployment already references one hashed template (infrastructureRef → KubevirtMachineTemplate) and one unhashed template (bootstrap.configRef → TalosConfigTemplate) [4], so adopting the same hashed-name pattern for TalosConfigTemplate would be consistent and straightforward:

    1. Compute a hash of the rendered TalosConfigTemplate spec (same sha256sum | trunc 6 approach).
    2. Name it <release>-<group>-<hash>.
    3. Update MachineDeployment.spec.template.spec.bootstrap.configRef.name to include the hash.
    4. Preserve old TalosConfigTemplate objects until no MachineSet references them (the chart already does this for old KubevirtMachineTemplate objects) [5].

    I didn't find an existing issue or PR tracking this, so this appears to be the first report.

    To reply, just mention @dosu.


    Share context across your team and agents. Try Dosu.

    Leave Feedback Learn about cozystack with Dosu Add Dosu to your team

  2. added 2 commits that reference this issue on Sep 21, 2026
    7b1a69e
    03c32e9
  3. added
    kind/bugCategorizes issue or PR as related to a bug
    area/kubernetesIssues or PRs related to the tenant Kubernetes app
    triage/acceptedIndicates an issue is ready to be actively worked on
    priority/important-soonMust be staffed and worked on either currently, or very soon, ideally in time for the next release
    and removed
    triage/needs-triageIndicates an issue needs triage by a maintainer
    on Sep 23, 2026
  4. added a commit that references this issue on Sep 29, 2026
    84f4890
  5. added a commit that references this issue on Sep 29, 2026
    c49afb0
  6. added a commit that references this issue on Sep 30, 2026
    2002266
  7. added a commit that references this issue on Sep 30, 2026
    0bc3f9f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/kubernetesIssues or PRs related to the tenant Kubernetes appkind/bugCategorizes issue or PR as related to a bugpriority/important-soonMust be staffed and worked on either currently, or very soon, ideally in time for the next releasetriage/acceptedIndicates an issue is ready to be actively worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions