From bdc43bb1d63f291d38b66a3b698a5503a50e82e0 Mon Sep 17 00:00:00 2001 From: Oleks Date: Tue, 2 Jun 2026 03:24:52 +0300 Subject: [PATCH] fix(deploy): align fleet-overlay blueprint with the live kotkan deploy The deploy/fleet-overlay templates had drifted from what actually runs in anton-helm-workloads (verified live + against the emdash-kotkanagrilli reference). Canonical design co-locates everything in the `kotkan` namespace: - source.yaml: GitRepository flux-system -> kotkan, so the HelmRelease chart sourceRef resolves same-namespace (no cross-namespace ref). - secrets.yaml: deploy-key Secret -> kotkan, defined once in the staging overlay; dropped the duplicate definition from the production overlay (production references the shared key by name). - image-automation.yaml: IUA write-back sourceRef anton-workloads-image-automation/flux-system -> anton-helm-workloads/kotkan (the existing read source already has push access). - README.md / DEPLOYMENT.md: namespace + ownership docs corrected. --- DEPLOYMENT.md | 2 +- deploy/fleet-overlay/README.md | 12 ++++--- .../image-automation.yaml | 17 +++++---- .../cms-plugins-production/secrets.yaml | 36 +++++-------------- .../cms-plugins-production/source.yaml | 6 +++- .../cms-plugins-staging/image-automation.yaml | 17 +++++---- .../cms-plugins-staging/secrets.yaml | 18 ++++++---- .../cms-plugins-staging/source.yaml | 6 +++- 8 files changed, 58 insertions(+), 56 deletions(-) diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 1c7a5dc..4800131 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -127,7 +127,7 @@ Each env has two distinct Secrets: | Secret | Namespace | Purpose | |---|---|---| -| `cms-plugins-deploy-key` | `flux-system` | SSH deploy key for Flux to clone `cms-plugins` (one pair shared between staging + production — same key reads both branches). | +| `cms-plugins-deploy-key` | `kotkan` | SSH deploy key for Flux to clone `cms-plugins` (one pair shared between staging + production — same key reads both branches). Defined once in the staging overlay; co-located with the GitRepositories in `kotkan` so the `secretRef` is same-namespace. | | `cms-plugins--secrets` | `kotkan` | Env vars the pod consumes via `existingSecret`. Required key: `EMDASH_ENCRYPTION_KEY`. | To rotate a credential: diff --git a/deploy/fleet-overlay/README.md b/deploy/fleet-overlay/README.md index 0fd52d8..2c15cfd 100644 --- a/deploy/fleet-overlay/README.md +++ b/deploy/fleet-overlay/README.md @@ -30,11 +30,13 @@ layout in `~/projects/servers/fleet/apps/base/`: tag in the Gitea OCI registry, resolves the current digest, and rewrites the digest setter in `helmrelease.yaml` (which is what actually makes `helm upgrade` see a change when CI retags the image). -- `secrets.yaml` — two Secrets per env: the SSH deploy key Flux uses to - clone this repo (`cms-plugins-deploy-key`, in `flux-system`), and the - pod's env-var secret (`cms-plugins-{staging,production}-secrets`, in - `kotkan`). **Templates here are NOT encrypted** — sops-encrypt them - before pushing to anton-helm-workloads. +- `secrets.yaml` — the pod's env-var secret + (`cms-plugins-{staging,production}-secrets`, in `kotkan`). The staging + overlay's `secrets.yaml` additionally defines the shared SSH deploy key + (`cms-plugins-deploy-key`, also in `kotkan` so the GitRepository + `secretRef` resolves same-namespace); production references that same key + by name and does NOT redefine it. **Templates here are NOT encrypted** — + sops-encrypt them before pushing to anton-helm-workloads. - `kustomization.yaml` — bundles the above. ## Why this lives in two repos diff --git a/deploy/fleet-overlay/cms-plugins-production/image-automation.yaml b/deploy/fleet-overlay/cms-plugins-production/image-automation.yaml index 89efcf8..9dcb885 100644 --- a/deploy/fleet-overlay/cms-plugins-production/image-automation.yaml +++ b/deploy/fleet-overlay/cms-plugins-production/image-automation.yaml @@ -41,11 +41,14 @@ spec: # tag is reassigned (without digest, tag stays `production` literal and # helm upgrade is a no-op). # -# NOTE: `sourceRef` must reference a GitRepository that points at -# THIS workloads repo (anton-helm-workloads) with write access. If it -# doesn't exist yet, create one alongside this manifest. The -# emdash-kotkanagrilli equivalent uses `oleks-fleet-image-automation` -# because its HelmReleases live in the fleet repo. +# NOTE: `sourceRef` is the WRITE-back target — a GitRepository (with a +# write-capable deploy key) pointing at the workloads repo this manifest +# lives in. We reuse the same `anton-helm-workloads` GitRepository in +# `kotkan` that Flux already uses to READ these workloads; its deploy key +# has push access, so IUA commits the pinned digest straight back to +# `main`. (The emdash-kotkanagrilli reference instead uses a dedicated +# `oleks-fleet-image-automation` source because its workloads live in the +# fleet repo — same idea, different repo.) apiVersion: image.toolkit.fluxcd.io/v1 kind: ImageUpdateAutomation metadata: @@ -55,8 +58,8 @@ spec: interval: 1m sourceRef: kind: GitRepository - name: anton-workloads-image-automation - namespace: flux-system + name: anton-helm-workloads + namespace: kotkan git: checkout: ref: diff --git a/deploy/fleet-overlay/cms-plugins-production/secrets.yaml b/deploy/fleet-overlay/cms-plugins-production/secrets.yaml index bbb7305..811df2a 100644 --- a/deploy/fleet-overlay/cms-plugins-production/secrets.yaml +++ b/deploy/fleet-overlay/cms-plugins-production/secrets.yaml @@ -1,43 +1,25 @@ -# Two secrets per environment: -# 1. cms-plugins-deploy-key — Flux's SSH key for cloning the production branch -# of cms-plugins (only `read` on this Gitea repo). -# One pair is shared between production + production; -# commit it under whichever env directory is -# applied first. -# 2. cms-plugins-production-secrets — env vars consumed by the pod via the +# Secret for the production environment: +# cms-plugins-production-secrets — env vars consumed by the pod via the # chart's `existingSecret`. EMDASH_ENCRYPTION_KEY # is required; everything else is optional. # -# These are TEMPLATES — encrypt them with sops before committing to the +# NOTE: the Flux SSH deploy key (cms-plugins-deploy-key) is NOT defined here. +# It is a single shared key defined once in the staging overlay's secrets.yaml +# (namespace `kotkan`); this env's source.yaml references it by name. Defining +# it again here would create a duplicate Secret (same name + namespace) with +# last-write-wins ambiguity. Mirrors the emdash-kotkanagrilli reference. +# +# This is a TEMPLATE — encrypt it with sops before committing to the # anton-helm-workloads repo: # # sops --encrypt --age secrets.yaml > secrets.enc.yaml # mv secrets.enc.yaml secrets.yaml # # Generation: -# ssh-keygen -t ed25519 -f /tmp/cms-plugins-deploy -N "" -# → upload /tmp/cms-plugins-deploy.pub to Gitea: Repo Settings → Deploy -# Keys → "cms-plugins Flux deploy", read-only. # openssl rand -hex 32 → EMDASH_ENCRYPTION_KEY (one per env, do not reuse). --- apiVersion: v1 kind: Secret -metadata: - name: cms-plugins-deploy-key - namespace: flux-system -type: Opaque -stringData: - identity: | - -----BEGIN OPENSSH PRIVATE KEY----- - REPLACE_WITH_PRIVATE_KEY - -----END OPENSSH PRIVATE KEY----- - identity.pub: | - ssh-ed25519 REPLACE_WITH_PUBLIC_KEY flux@cms-plugins - known_hosts: | - git.oleks.space REPLACE_WITH_HOST_KEY ---- -apiVersion: v1 -kind: Secret metadata: name: cms-plugins-production-secrets namespace: kotkan diff --git a/deploy/fleet-overlay/cms-plugins-production/source.yaml b/deploy/fleet-overlay/cms-plugins-production/source.yaml index c2836bb..3ace8d2 100644 --- a/deploy/fleet-overlay/cms-plugins-production/source.yaml +++ b/deploy/fleet-overlay/cms-plugins-production/source.yaml @@ -6,7 +6,11 @@ apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: cms-plugins-production - namespace: flux-system + # Co-located with the HelmRelease in `kotkan` so the chart sourceRef is a + # same-namespace reference (Flux commonly disables cross-namespace source + # refs). Matches the emdash-kotkanagrilli reference overlay and the live + # deploy in anton-helm-workloads. + namespace: kotkan spec: interval: 1m0s url: ssh://git@git.oleks.space/oleks/cms-plugins.git diff --git a/deploy/fleet-overlay/cms-plugins-staging/image-automation.yaml b/deploy/fleet-overlay/cms-plugins-staging/image-automation.yaml index 8a8ae36..b10fbd5 100644 --- a/deploy/fleet-overlay/cms-plugins-staging/image-automation.yaml +++ b/deploy/fleet-overlay/cms-plugins-staging/image-automation.yaml @@ -41,11 +41,14 @@ spec: # tag is reassigned (without digest, tag stays `staging` literal and # helm upgrade is a no-op). # -# NOTE: `sourceRef` must reference a GitRepository that points at -# THIS workloads repo (anton-helm-workloads) with write access. If it -# doesn't exist yet, create one alongside this manifest. The -# emdash-kotkanagrilli equivalent uses `oleks-fleet-image-automation` -# because its HelmReleases live in the fleet repo. +# NOTE: `sourceRef` is the WRITE-back target — a GitRepository (with a +# write-capable deploy key) pointing at the workloads repo this manifest +# lives in. We reuse the same `anton-helm-workloads` GitRepository in +# `kotkan` that Flux already uses to READ these workloads; its deploy key +# has push access, so IUA commits the pinned digest straight back to +# `main`. (The emdash-kotkanagrilli reference instead uses a dedicated +# `oleks-fleet-image-automation` source because its workloads live in the +# fleet repo — same idea, different repo.) apiVersion: image.toolkit.fluxcd.io/v1 kind: ImageUpdateAutomation metadata: @@ -55,8 +58,8 @@ spec: interval: 1m sourceRef: kind: GitRepository - name: anton-workloads-image-automation - namespace: flux-system + name: anton-helm-workloads + namespace: kotkan git: checkout: ref: diff --git a/deploy/fleet-overlay/cms-plugins-staging/secrets.yaml b/deploy/fleet-overlay/cms-plugins-staging/secrets.yaml index 82590e8..ae19e78 100644 --- a/deploy/fleet-overlay/cms-plugins-staging/secrets.yaml +++ b/deploy/fleet-overlay/cms-plugins-staging/secrets.yaml @@ -1,9 +1,13 @@ -# Two secrets per environment: -# 1. cms-plugins-deploy-key — Flux's SSH key for cloning the staging branch -# of cms-plugins (only `read` on this Gitea repo). -# One pair is shared between staging + production; -# commit it under whichever env directory is -# applied first. +# Secrets for the staging environment: +# 1. cms-plugins-deploy-key — Flux's SSH key for cloning cms-plugins (only +# `read` on this Gitea repo). ONE pair is shared +# between staging + production and is defined HERE +# (staging) only — the production source.yaml +# references it by name. Both GitRepositories and +# this Secret live in `kotkan`, so the secretRef +# resolves same-namespace. (Mirrors the +# emdash-kotkanagrilli reference, where the shared +# deploy key is defined once in the staging overlay.) # 2. cms-plugins-staging-secrets — env vars consumed by the pod via the # chart's `existingSecret`. EMDASH_ENCRYPTION_KEY # is required; everything else is optional. @@ -24,7 +28,7 @@ apiVersion: v1 kind: Secret metadata: name: cms-plugins-deploy-key - namespace: flux-system + namespace: kotkan type: Opaque stringData: identity: | diff --git a/deploy/fleet-overlay/cms-plugins-staging/source.yaml b/deploy/fleet-overlay/cms-plugins-staging/source.yaml index 85ad7d9..3a01770 100644 --- a/deploy/fleet-overlay/cms-plugins-staging/source.yaml +++ b/deploy/fleet-overlay/cms-plugins-staging/source.yaml @@ -6,7 +6,11 @@ apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: cms-plugins-staging - namespace: flux-system + # Co-located with the HelmRelease in `kotkan` so the chart sourceRef is a + # same-namespace reference (Flux commonly disables cross-namespace source + # refs). Matches the emdash-kotkanagrilli reference overlay and the live + # deploy in anton-helm-workloads. + namespace: kotkan spec: interval: 1m0s url: ssh://git@git.oleks.space/oleks/cms-plugins.git