L3 — GitOps bootstrap (Day-1)
Once a cluster exists, GitOps takes over. Hub is driven directly; spokes via the ACM pull model.
Flow
platform/gitops (GitLab, private) ── Argo auths with read-only deploy token
│
▼
Hub Argo (openshift-gitops) ── syncs hub/ (from bootstrap/root-app.yaml, app-of-apps)
│
├─ GitOpsCluster + Placement + ApplicationSet(spoke-config) ← ACM pull model
│ │
│ ▼ ManifestWork
│ Spoke Argo (openshift-gitops on wl / wl-dr) ── syncs spoke/overlays/<cluster>
│
└─ ACM policies install the gitops operator + repo secret on each spoke
Key mechanics
| Piece | Requirement |
|---|---|
| Root app | bootstrap/root-app.yaml (hub-root, app-of-apps, path hub) |
| Pull model | GitOpsCluster CR (without it, 0 apps generated) + appset-controller RBAC for placementdecisions + acm-placement CM (statusListKey: decisions) |
| Per-cluster spoke config | spoke/base + spoke/overlays/{wl,wl-dr} (Argo ApplicationSet spoke/overlays/{{name}}) |
| Sync waves | order the platform bring-up |
Out-of-band bootstrap (per cluster, in order)
These are not GitOps (secrets / stale runtime state) — idempotent scripts in scripts/:
| Step | Action |
|---|---|
| 1 | Install OpenShift GitOps operator + oc apply -f bootstrap/root-app.yaml |
| 2 | Seed gitops-repo deploy-token secret (Vault apps/gitlab/argo-deploy) so Argo can pull |
| 3 | scripts/reintegrate-vault-k8s-auth.sh <hub\|spoke> — reviewer SA + rewrite the stale Vault k8s-auth mount |
| 4 | Node labels: scripts/label-odf-nodes.sh, label-infra-nodes.sh |
Pull-model gotchas (see Gotchas)
- Credential-less
gitops-reposecret →authentication required→ spoke never syncs. Merge the deploy-token creds. - Stuck Argo sync op (old
startedAt, retrying) pins stale manifests → recreate the app (finalizer-clear+oc delete app --cascade=orphan, ManifestWork recreates it fresh). - StorageCluster won’t take a field via Argo (client-side-apply lock) → the SC carries
ServerSideApply=true; if stuck, remove itslast-applied-configurationannotation.
GitOps vs. out-of-band
The root app + ApplicationSet are GitOps; the 4 bootstrap steps above are out-of-band per-cluster seeds (see Rebuild Phase 1–2).