Skip to content

fix(crossplane-providers): install provider-helm as the dependsOn-derived CR (one CR, not two) - #154

Merged
patrick-hermann-sva merged 1 commit into
mainfrom
fix/provider-helm-single-cr
Jul 23, 2026
Merged

patrick-hermann-sva merged 1 commit into
mainfrom
fix/provider-helm-single-cr

Conversation

@patrick-hermann-sva

Copy link
Copy Markdown
Contributor

Fixes stuttgart-things/crossplane-configurations#147.

Problem

provider-helm was installed here as CR provider-helm from xpkg.upbound.io. Four Configurations (bootstrap/{platform,flux-init,cni,vault-config}) dependsOn provider-helm from xpkg.crossplane.io, from which the package manager derives a second Provider CR crossplane-contrib-provider-helm. Two Provider CRs for the same package (same digest) fight over the releases.helm.m.crossplane.io CRD:

crossplane-contrib-provider-helm  HEALTHY=False
  UnhealthyPackageRevision: cannot establish control of object:
  releases.helm.m.crossplane.io is already controlled by provider-helm-<digest>

That fails the machinery bootstrap's kubectl wait provider --all --for=condition=Healthy gate. Verified on a fresh LabUL machinery cluster. provider-kubernetes does not hit this — it is (deliberately) not installed here and comes solely via dependsOn, so there is only one CR.

Unlike the function-kcl cross-mirror pair (functions own no CRDs → benign, per crossplane-configurations CLAUDE.md), providers own CRDs, so there must be exactly one provider-helm CR.

Fix

Name this install crossplane-contrib-provider-helm and source it from xpkg.crossplane.io — exactly what the dependsOn derives. The provider helmfile runs before the Configurations, so this CR exists first; the dependsOn then finds it (carrying the runtimeConfigRef + cluster-admin DeploymentRuntimeConfig needed for InjectedIdentity) instead of adding its own. One CR, healthy.

Blast radius

  • ClusterProviderConfigs are named in-cluster, independent of the provider CR name — nothing referencing the provider by config name changes.
  • The DeploymentRuntimeConfig, ServiceAccount and ClusterRoleBinding all derive from $p.name, so they rename with it, consistently.
  • kind1 is not affected until an explicit re-apply: no ArgoCD auto-sync, and its crossplane-providers release is a one-shot from bootstrap (revision 1, 2026-07-10). A future re-apply moves it to the fixed single-CR state.

…ived CR

provider-helm was installed here as `provider-helm` from xpkg.upbound.io.
Four Configurations (crossplane-configurations bootstrap/{platform,
flux-init,cni,vault-config}) dependsOn provider-helm from
xpkg.crossplane.io, from which the package manager derives a second
Provider CR `crossplane-contrib-provider-helm`. Two Provider CRs for the
same package fight over the releases.helm.m.crossplane.io CRD — the loser
is stuck UnhealthyPackageRevision, which fails the machinery bootstrap's
`kubectl wait provider --all --for=condition=Healthy` gate.

Verified on a fresh LabUL machinery cluster. Unlike the function-kcl
cross-mirror pair (functions own no CRDs, benign), providers own CRDs, so
there must be exactly ONE provider-helm CR.

Fix: name this install `crossplane-contrib-provider-helm` and source it
from xpkg.crossplane.io — exactly what the dependsOn derives. The provider
helmfile runs before the Configurations, so this CR exists first; the
dependsOn then finds it (carrying the runtimeConfigRef + cluster-admin
DeploymentRuntimeConfig for InjectedIdentity) instead of adding its own.
One CR, healthy.

ClusterProviderConfigs are named `in-cluster`, independent of the provider
CR name, so nothing referencing the provider by config name changes.
kind1 is unaffected until an explicit re-apply (no ArgoCD auto-sync; the
release is a one-shot from bootstrap).

Refs stuttgart-things/crossplane-configurations#147
@patrick-hermann-sva
patrick-hermann-sva merged commit d1dfc3f into main Jul 23, 2026
0 of 4 checks passed
patrick-hermann-sva added a commit that referenced this pull request Sep 19, 2026
…endsOn (#163)

provider-kubernetes, provider-proxmox-bpg and the xpkg.crossplane.io twins
of function-kcl and function-patch-and-transform were never installed
explicitly. The package manager pulled them in for the Configurations'
dependsOn, at the newest version the constraint allowed that day, so two
clusters built from the same commit differed. A throwaway machinery cluster
(u26-kindtest, 2026-09-19) got provider-kubernetes 1.3.1, proxmox-bpg
1.19.3, kcl 0.12.3 and p&t 0.10.11 next to u26-kind3's 1.2.1, 1.18.0,
0.12.2 and 0.10.8.

Each is now listed under exactly the name and source the package manager
derives from the dependsOn, as provider-helm already is (#154), so the
dependency finds this object instead of adding its own. Versions are
u26-kind3's.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

This branch was successfully deployed

No deployments
k8s — 12703cf3 Deployed Jul 23, 2026 by patrick-hermann-sva via Analyze-Changed-Charts #244
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants