--- # Flux Kustomization: PLATFORM services (cluster-wide). Reconciles ./platform. # Phase 0 STUB. Realizes R-GITOPS-01/03 (pull-based reconcile + drift correction) and # R-ENV-02 (env differences supplied ONLY via substituteFrom cluster-vars). apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: platform namespace: flux-system spec: interval: 10m retryInterval: 2m timeout: 5m prune: true # drift correction: delete resources removed from git (R-GITOPS-03) wait: true # block `apps` until platform is healthy # ORDERING FIX (2026-09-01 incident: a substitution race that failed OPEN broke Cilium). # # `cluster-vars` — the ConfigMap every substituting Kustomization reads — is APPLIED by the root # `flux-system` Kustomization (clusters//sync.yaml), not by this one. Without an edge here, # `platform` could render a manifest from revision N against the revision N-1 `cluster-vars`, so a # NEWLY ADDED knob was undefined and (non-strict substitution) silently became the EMPTY STRING. # That is how `k8sServiceHost: ""` reached the Cilium HelmRelease. # # `dependsOn` is REVISION-gated, not merely Ready-gated (verified against # kustomize-controller v1.4.0 `kustomization_controller.go :: checkDependencies`, our version): # when the dependency shares a GitRepository with the dependent, the dependent cannot reconcile # revision N until the dependency has APPLIED revision N. Applying revision N is exactly what # writes a newly-added `cluster-vars` knob — so this one edge closes the race. # # `platform` is the ONLY Kustomization in the graph with no `dependsOn`; every other substituting # consumer (platform-config, apps-wave-0/1/2, apps-vms, oauth2-proxy, headlamp, homepage, crafty, # velero) chains transitively through it. One edge therefore protects the whole graph. # # TRADE-OFF — READ THIS BEFORE YOU CURSE IT: the root is now a GATE. A malformed manifest # ANYWHERE under the root's path (clusters/, which includes clusters/base) fails the root # Kustomization and therefore stops `platform` and EVERYTHING downstream, where before this edge # the rest of the graph would have kept reconciling. That is deliberate and fail-closed: a broken # entrypoint should stop the line, not let consumers render against a half-applied variable set. # No deadlock risk — the root runs `wait: false`, so it reaches Ready on APPLY success and never # health-gates its own children (see clusters/dev/sync.yaml). dependsOn: - name: flux-system # the ROOT Kustomization (sync.yaml) that applies cluster-vars sourceRef: kind: GitRepository name: flux-system path: ./platform # R-ENV-02: the ONLY place environment differences enter platform manifests. # dev/prod overlays patch the cluster-vars ConfigMap; the base manifests are never forked. postBuild: substituteFrom: - kind: ConfigMap name: cluster-vars # TODO(WS-SEC, Phase 1): enable SOPS decryption once the age key exists (ADR-0007). # decryption: # provider: sops # secretRef: # name: sops-age # TODO(PM): the top-level ./platform/kustomization.yaml must include platform/kyverno/ # (owned by the policy engineer, WS-TEST). See platform/README.md integration TODO.