diff --git a/deploy/README.md b/deploy/README.md index 559f2bf..c09fcab 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -11,9 +11,9 @@ hand-deployed to prod.** Local/dev is Helm/Skaffold on kind. deploy/ ├── README.md # this file ├── argocd/ -│ ├── project.yaml # AppProject "fuzekeys" (sourceRepos + destinations) -│ ├── app-of-apps.yaml # root Application -> deploy/argocd/applications (recurse) +│ ├── app-of-apps.yaml # root Application (project: default) -> deploy/argocd/applications (recurse) │ ├── applications/ +│ │ ├── project.yaml # AppProject "fuzekeys" (sync-wave -1, Prune=false) — GitOps-managed │ │ ├── fuzekeys-platform.yaml # Helm Application -> deploy/helm/fuzekeys (values-contabo) │ │ └── fuzekeys-sealed.yaml # Application -> deploy/argocd/sealed (SealedSecrets) │ └── sealed/ # SealedSecrets (ciphertext only) — generated by seal-secrets.yml @@ -32,13 +32,23 @@ deploy/ FuzeKeys is a single independently-lifecycled product, so it gets its **own** Argo project + app-of-apps (not folded into the FuzeFront umbrella): -1. Register **`deploy/argocd/app-of-apps.yaml`** in Argo once (and the AppProject - `deploy/argocd/project.yaml`). Argo then discovers the child Applications in - `deploy/argocd/applications/` (recurse) and reconciles them: +1. Register **`deploy/argocd/app-of-apps.yaml`** in Argo once — a single + `kubectl apply`. The root runs in the built-in **`default`** project and + recurses `deploy/argocd/applications/`, creating everything else from git: + - **`fuzekeys`** (AppProject) — reconciled FIRST (`sync-wave: -1`, + `Prune=false`) so the child Applications never hit InvalidSpecError for a + missing project. This is why the root is in `default`, not `fuzekeys`: it + must create the `fuzekeys` project without depending on it existing yet. - **`fuzekeys-platform`** — the Helm chart into namespace `fuzekeys` (`automated{prune,selfHeal}`, `CreateNamespace`, `ServerSideApply`, retry backoff). - **`fuzekeys-sealed`** — the SealedSecrets in `deploy/argocd/sealed/` (`prune:false` — never auto-prune secrets). + + > The AppProject is now GitOps-managed (it used to be a separate manual + > `kubectl apply` that, if missed, left the root app-of-apps InvalidSpec → + > OutOfSync/Missing). On a hardened *shared* Argo, confirm the `default` + > project isn't locked down; if it is, register the root under a small + > dedicated bootstrap project instead. 2. All Applications track **`targetRevision: master`** (this repo's default branch). ## Consuming FuzeInfra (one-way dependency) diff --git a/deploy/argocd/app-of-apps.yaml b/deploy/argocd/app-of-apps.yaml index d299677..6c780bf 100644 --- a/deploy/argocd/app-of-apps.yaml +++ b/deploy/argocd/app-of-apps.yaml @@ -8,8 +8,16 @@ metadata: spec: # Root "app of apps": Argo watches deploy/argocd/applications/ and reconciles # every child Application it finds there (recurse). Register THIS one manifest - # in Argo once; the platform + sealed Applications then flow from git. - project: fuzekeys + # in Argo once; the AppProject + platform + sealed Applications then flow from + # git. + # + # The root runs in the built-in `default` project (NOT `fuzekeys`) on purpose: + # it is now responsible for CREATING the `fuzekeys` AppProject (see + # applications/project.yaml). If the root referenced `fuzekeys` it would be + # InvalidSpec until that project exists and could never create it — the + # chicken-and-egg that left `fuzekeys-apps` OutOfSync/Missing. The workloads + # stay isolated under the `fuzekeys` project via the child Applications. + project: default source: repoURL: https://github.com/izzywdev/FuzeKeys.git targetRevision: master diff --git a/deploy/argocd/project.yaml b/deploy/argocd/applications/project.yaml similarity index 63% rename from deploy/argocd/project.yaml rename to deploy/argocd/applications/project.yaml index 2bfd5ac..1d495dc 100644 --- a/deploy/argocd/project.yaml +++ b/deploy/argocd/applications/project.yaml @@ -5,6 +5,14 @@ metadata: namespace: argocd annotations: fuzekeys.io/owner-repo: izzywdev/FuzeKeys + # Created FIRST within the root app-of-apps sync so the child Applications + # (which reference `project: fuzekeys`) never hit InvalidSpecError for a + # missing project — the failure mode that left `fuzekeys-apps` Missing. + argocd.argoproj.io/sync-wave: "-1" + # NEVER auto-prune the AppProject: if this manifest transiently fails to + # render, prune would delete the project and cascade every child app into + # InvalidSpec. Pinned off regardless of the root app-of-apps prune policy. + argocd.argoproj.io/sync-options: Prune=false spec: description: >- FuzeKeys — keys / secrets / PII-tokenization product — deployed onto the