GitOps Overview
Purpose
Lumie's infrastructure repo uses Argo CD's app-of-apps pattern to reconcile the cluster from lumie-infra. Ansible only performs the first install of Argo CD and a small set of bootstrap secrets; after that, desired state is expected to flow from Git into Argo CD Applications and then into namespaced workloads.
This page is an overview document for developers changing lumie-infra, bootstrap automation, or the GitOps delivery path. For controller-specific detail, see Argo CD, CI/CD, Gitea, Tekton, and Zot.
Source Paths
| Path | Role |
|---|---|
lumie-infra/provision/ansible/roles/argocd-bootstrap/tasks/main.yml | First-install path for Argo CD, bootstrap namespaces, and static MinIO or Vault secrets |
lumie-infra/provision/ansible/roles/argocd-bootstrap/defaults/main.yml | Root app list Ansible applies after Argo CD is ready |
lumie-infra/bootstrap/application.yaml | Root Application for the bootstrap subtree, synced at wave -1 |
lumie-infra/bootstrap/kustomization.yaml | Bootstrap child order: MinIO, Zot, Vault, then Gitea |
lumie-infra/{platform,storage,security,observability,applications}/application.yaml | Root Applications for the remaining GitOps layers |
lumie-infra/applications/kustomization.yaml | Application subtree registration, including Tekton, Argo CD self-management, and Lumie services |
lumie-infra/applications/cluster-bootstrap/** | Cluster-scoped one-shot resources such as ClusterIssuer and default StorageClass |
Ownership Boundaries
| Layer | Source of truth | Notes |
|---|---|---|
| First install | provision/ansible/roles/argocd-bootstrap/** | Installs Argo CD with a minimal Helm release and applies the root Application manifests |
| Root GitOps tree | bootstrap/, platform/, storage/, security/, observability/, applications/ | Each directory owns one root Application CR and the subtree beneath it |
| Child applications | applications/**, platform/**, and peer directories | Individual apps own namespace-scoped workload manifests and Helm values |
| Build output | applications/tekton/ci-cd/** | Tekton builds images and updates deployment values; Argo CD performs the actual rollout |
The cluster is not meant to be hand-configured after bootstrap. If a controller, secret, queue, or ingress is required long-term, the desired state should exist in lumie-infra rather than only in the live cluster.
Runtime Flow
The sync ordering visible in code is:
| Stage | Evidence |
|---|---|
| Root bootstrap subtree before the rest | bootstrap/application.yaml sets argocd.argoproj.io/sync-wave: "-1" |
| Cluster-scoped bootstrap before normal applications | applications/cluster-bootstrap/argocd.yaml sets sync wave -2 |
| Bootstrap internals | bootstrap/kustomization.yaml orders minio -> zot -> vault -> gitea |
Operational Notes
- All root Applications use automated sync with
prune: trueandselfHeal: true. applications/argocd/argocd.yamlmakes Argo CD self-managed after the initial Ansible install.- GitOps access patterns are split: Argo CD root Applications still pull
lumie-infrafromhttps://github.com/Lumie-Edu/lumie-infra.git, while the CI/CD path clones and updates repos through in-cluster Gitea. See CI/CD and Gitea.
Contract Drift
Inspected sources do not fully agree on the current GitOps boundary:
| Source | Claim |
|---|---|
provision/ansible/roles/argocd-bootstrap/defaults/main.yml | Bootstrap still lists web-apps/application.yaml in app_of_apps_paths |
lumie-infra repo tree | No web-apps/application.yaml path exists in the inspected repo |
| Live cluster on June 14, 2026 | Only six root Applications exist; no web-apps root Application is present |
Document the six-root model as the active contract until the bootstrap defaults are cleaned up.
There is also a Git host split that needs to stay visible:
| Source | Claim |
|---|---|
| Root Argo CD Applications and Ansible bootstrap | Pull lumie-infra from GitHub |
applications/tekton/ci-cd/manifests/tasks/git-update-values.yaml | Pushes deployment value changes to http://gitea-http.gitea.svc.cluster.local:3000/Lumie-Edu/lumie-infra.git |
The repo does not contain the bridge between those two locations. Treat that as an operational dependency outside the inspected GitOps manifests.
Verification
Use repo and cluster checks together when changing the GitOps slice:
cd lumie-infra
rg -n "sync-wave|app_of_apps_paths|repoURL: https://github.com/Lumie-Edu/lumie-infra.git" \
bootstrap applications platform storage security observability provision/ansible
kubectl get applications -n argocd
kubectl get applications bootstrap platform storage security observability applications -n argocd -o wide
Success signals:
- Repo checks still show the six checked-in root
Applicationpaths plus thecluster-bootstrapchild application underapplications/. - The live cluster shows the six active root applications
bootstrap,platform,storage,security,observability, andapplications. - No root
Applicationnamedweb-appsexists unless the stale Ansible default is reintroduced and backed by a real repo path.