# Argo CD — noble (bootstrap) **Prerequisites:** cluster **Ready**, **Traefik** + **cert-manager**; DNS **`argo.apps.noble.lab.pcenicni.dev`** → Traefik **`192.168.50.211`** (see **`values.yaml`**). ## 1. Install ```bash helm repo add argo https://argoproj.github.io/argo-helm helm repo update helm upgrade --install argocd argo/argo-cd \ --namespace argocd \ --create-namespace \ --version 9.4.17 \ -f clusters/noble/bootstrap/argocd/values.yaml \ --wait ``` **RBAC:** `values.yaml` sets **`policy.default: role:readonly`** and **`g, admin, role:admin`** so the local **`admin`** user keeps full access while future OIDC users default to read-only until you add **`policy.csv`** mappings. ## 2. UI / CLI address **HTTPS:** `https://argo.apps.noble.lab.pcenicni.dev` (Ingress via Traefik; cert from **`values.yaml`**). ```bash kubectl get ingress -n argocd ``` Log in as **`admin`**; initial password: ```bash kubectl -n argocd get secret argocd-initial-admin-secret \ -o jsonpath='{.data.password}' | base64 -d echo ``` Change the password in the UI or via `argocd account update-password`. ### TLS: changing ClusterIssuer (e.g. staging → prod) If **`helm upgrade --wait`** fails with *Secret was previously issued by `letsencrypt-staging`* (or another issuer), cert-manager will not replace the TLS Secret in place. Remove the old cert material once, then upgrade again: ```bash kubectl -n argocd delete certificate argocd-server --ignore-not-found kubectl -n argocd delete secret argocd-server-tls --ignore-not-found helm upgrade --install argocd argo/argo-cd -n argocd --create-namespace \ --version 9.4.17 -f clusters/noble/bootstrap/argocd/values.yaml --wait ``` ## 3. Register this repo (if private) Use **Settings → Repositories** in the UI, or `argocd repo add` / a `Secret` of type `repository`. ## 4. App-of-apps (GitOps) **Ansible** (`ansible/playbooks/noble.yml`) runs **`kubectl apply -k clusters/noble/bootstrap`** from **`noble_platform`**, then Helm for the platform stack, **then** **`noble_authentik`**, **`noble_trivy`**, **`noble_velero`**, and **only then** (play **`tasks:`**) **`noble_argocd`** `applications_post_platform.yml` applies **`root-application.yaml`**, **`bootstrap-root-application.yaml`**, and **`kubectl apply -k clusters/noble/bootstrap/argocd/app-of-apps`**. That order keeps **Ansible Helm first** and lets Argo **take ownership** when you sync or enable automation (no premature SSA vs Helm). 1. Edit **`root-application.yaml`** and **`bootstrap-root-application.yaml`**: set **`repoURL`** and **`targetRevision`**. The **`resources-finalizer.argocd.argoproj.io/background`** finalizer uses Argo’s path-qualified form so **`kubectl apply`** does not warn about finalizer names. 2. Optional add-on apps: add **`Application`** manifests under **`clusters/noble/apps/`** (see **`clusters/noble/apps/README.md`**). 3. **Bootstrap kustomize** (namespaces, datasource, etc.): **`noble-bootstrap-root`** syncs **`clusters/noble/bootstrap`** (no **`argocd/app-of-apps/`** in that kustomization). Leaf **`Application`** manifests live under **`argocd/app-of-apps/`**; Ansible applies that directory **after** all **`noble_*`** Helm roles in **`noble.yml`** (see §4) so Argo does not SSA charts before Helm. The root app uses **manual** sync; each leaf app is **manual** until you enable automation (see **§5**). **`ansible/playbooks/noble.yml`**: roles **`noble_argocd`** (Argo Helm only), **`noble_platform`**, **`noble_authentik`**, **`noble_trivy`**, **`noble_velero`**, then play **`tasks`** run **`applications_post_platform`** when **`noble_argocd_apply_*`** flags are set in **`ansible/inventory/group_vars/all.yml`**. ```bash kubectl apply -f clusters/noble/bootstrap/argocd/root-application.yaml kubectl apply -f clusters/noble/bootstrap/argocd/bootstrap-root-application.yaml ``` If you migrated from older GitOps **`Application`** names, delete stale **`Application`** objects on the cluster (see **`clusters/noble/apps/README.md`**) then re-apply the roots. ## 5. After Ansible: enable automated sync for **noble-bootstrap-root** Do this only after **`ansible-playbook playbooks/noble.yml`** has finished successfully (including **`noble_platform`** / **`noble_authentik`** / **`noble_trivy`** Helm and the final **`applications_post_platform`** `kubectl apply` of leaf **Application** CRs). Until then, leave **manual** sync so Argo does not fight the playbook. **Required steps** 1. Confirm the cluster matches git for kustomize output (optional): `kubectl kustomize clusters/noble/bootstrap | kubectl diff -f -` or inspect resources in the UI. 2. Register the git repo in Argo if you have not already (**§3**). 3. **Refresh** the app so Argo compares **`clusters/noble/bootstrap`** to the cluster: Argo UI → **noble-bootstrap-root** → **Refresh**, or: ```bash argocd app get noble-bootstrap-root --refresh ``` 4. **Enable automated sync** (prune + self-heal), preserving **`CreateNamespace`**, using any one of: **kubectl** ```bash kubectl patch application noble-bootstrap-root -n argocd --type merge -p '{"spec":{"syncPolicy":{"automated":{"prune":true,"selfHeal":true},"syncOptions":["CreateNamespace=true"]}}}' ``` **argocd** CLI (logged in) ```bash argocd app set noble-bootstrap-root --sync-policy automated --auto-prune --self-heal ``` **UI:** open **noble-bootstrap-root** → **App Details** → enable **AUTO-SYNC** (and **Prune** / **Self Heal** if shown). 5. Trigger a sync if the app does not go green immediately: **Sync** in the UI, or `argocd app sync noble-bootstrap-root`. 6. **Leaf apps** (`noble-cilium`, `noble-kube-prometheus`, … under **`app-of-apps/`**) stay **manual** until you turn on **AUTO-SYNC** (or sync once) **per app** after Ansible has finished. Until then they only register intent in Argo; **Ansible** still performs the Helm installs in **`noble_*`** roles. When you are ready for Argo to own a chart, enable sync for that leaf app and **remove** the corresponding **`helm upgrade`** task from Ansible so only one controller manages the release. If **`helm upgrade`** failed with **conflict with `argocd-controller`**, a leaf app had already reconciled: apply the updated manifests (manual leaf sync), delete the conflicting **`Application`** with **`--cascade=false`** if needed, then re-run the playbook — or finish migration to Argo-only for that chart. After **`noble-bootstrap-root`** is automated and leaf apps are synced, **git** is the source of truth for **`clusters/noble/bootstrap/kustomization.yaml`** and the leaf **`Application`** specs. ## Versions Pinned in **`values.yaml`** comments (chart **9.4.17** / Argo CD **v3.3.6** at time of writing). Bump **`--version`** when upgrading.