--- # Flux Kustomization: WireGuard remote-access VPN — reconciles ./platform/vpn-ingress. # # POST-PLATFORM TIER (dependsOn platform-config), NON-GATING (wait:false). Not a line in # platform/kustomization.yaml, for the standard reason plus one specific to this component: # # * STANDARD: a leaf must never sit in the gating `platform` tier. While `platform` is not-Ready # NOTHING downstream reconciles — the incident behind the headlamp/oauth2-proxy/homepage moves # (DECISIONS-LOG: "Headlamp gating stall"). # * SPECIFIC, AND THE REASON THIS IS NOT A JUDGEMENT CALL: this DaemonSet cannot start until the # operator creates the out-of-band `wg-server-key` Secret (runbooks/vpn-remote-access.md # step 1). That is the correct fail-closed state — an unenrolled VPN must not come up — but in # the gating tier it would have been a self-inflicted platform-wide outage ON MERGE, with the # cause (a missing manual step) invisible from any Flux condition. # # WHY dependsOn platform-config AND NOT cilium. This component needs no Gateway, no TLS cert, no # Keycloak and no LB-IPAM pool — it has no HTTPRoute and no LoadBalancer Service, and hostNetwork # means it does not even need a Cilium endpoint. It could legally reconcile much earlier. It is # pinned behind platform-config anyway so that the ONE thing remote clients actually consume # through it — split-horizon DNS and the shared Gateway — exists by the time the tunnel does. # A tunnel that comes up before the things on the far side of it is a support call, not a feature. # # wait:false: nothing in the graph dependsOn this, and its pods are legitimately not-Ready whenever # the server key is absent or the `wireguard` kernel module has not been loaded on a node. Neither # condition should be able to gate anything else, even if a future resource is mistakenly pointed # at it. apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: vpn-ingress namespace: flux-system spec: interval: 10m retryInterval: 2m timeout: 5m prune: true wait: false dependsOn: - name: platform-config sourceRef: kind: GitRepository name: flux-system path: ./platform/vpn-ingress # REQUIRED, not boilerplate: platform/vpn-ingress/daemonset.yaml renders ${WG_CLIENT_CIDR} into # the config-assembly script. Without this block that token becomes the EMPTY STRING and the # Kustomization still reports Ready (Flux's substitution fails OPEN — ci: # flux-postbuild-substitution), leaving an initContainer that derives a server address of ".1/" # and a MASQUERADE rule with no source. Both fail loudly at pod start, but the Kustomization # would look healthy. postBuild: substituteFrom: - kind: ConfigMap name: cluster-vars # NO `decryption:` stanza is needed in the overlays: this path carries no *.sops.yaml. The server # key is an out-of-band Secret (platform/vpn-ingress/kustomization.yaml says what to do if that # ever changes).