116 lines
7.4 KiB
Markdown
116 lines
7.4 KiB
Markdown
# 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.5.14 \
|
||
-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.5.14 -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_velero`**, and **only then** (play **`tasks:`**) **`noble_argocd`** `applications_post_platform.yml` applies **`bootstrap-root-application.yaml`**, and **`kubectl apply -k clusters/noble/bootstrap/argocd/app-of-apps`**. **Trivy Operator** is **not** installed by Ansible; sync the **`noble-trivy-operator`** leaf app (or enable automation) after **`noble.yml`**. That order keeps **Ansible Helm first** and lets Argo **take ownership** when you sync or enable automation (no premature SSA vs Helm).
|
||
|
||
1. Edit **`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 a subdirectory under **`clusters/noble/apps/`** with its own **`kustomization.yaml`** (see **`clusters/noble/apps/README.md`**). The bootstrap kustomization includes **`../apps`**, so **`noble-bootstrap-root`** applies them with the rest of bootstrap static YAML.
|
||
3. **Bootstrap kustomize** (namespaces, datasource, optional **`clusters/noble/apps`**, etc.): **`noble-bootstrap-root`** syncs **`clusters/noble/bootstrap`**. Leaf chart **`Application`** manifests for core charts 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 bootstrap 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_velero`**, then play **`tasks`** run **`applications_post_platform`** when **`noble_argocd_apply_bootstrap_root_application`** is set in **`ansible/inventory/group_vars/all.yml`**. Trivy is deployed only via Argo (**`noble-trivy-operator`**).
|
||
|
||
```bash
|
||
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 bootstrap root.
|
||
|
||
**Trivy (`noble-trivy-operator`):** If an older install left an orphan **`ServiceMonitor`** named **`trivy-operator`** in **`monitoring`** (missing `meta.helm.sh/release-*` annotations), Helm/Argo will refuse to adopt it. Delete once, then sync **`noble-trivy-operator`**:
|
||
|
||
```bash
|
||
kubectl delete servicemonitor trivy-operator -n monitoring --ignore-not-found
|
||
```
|
||
|
||
## 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`** Helm, **`noble_velero`** if enabled, 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 for those charts (**Trivy Operator** is an exception — install/sync only via **`noble-trivy-operator`**). 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.5.14** / Argo CD **v3.4.2** at time of writing). Bump **`--version`** when upgrading.
|