Files
homelab/cluster/argocd/BOOTSTRAP.md
2026-05-18 13:20:42 -05:00

4.5 KiB

fastpass — ArgoCD Bootstrap

This document covers the manual steps required to bootstrap ArgoCD on the fastpass cluster. After these steps, all further changes are made via Git.

Prerequisites:

  • All 6 Talos nodes Ready (kubectl get nodes)
  • Cilium healthy (cilium status --wait)
  • IP pools applied (kubectl get ciliumloadbalancerippool)
  • city-hall has helm, kubectl, and talosctl installed
  • SSH keypair for ArgoCD → Gitea exists at /home/wed/.ssh/argocd_gitea

Step 1 — Create the argocd namespace

kubectl apply -f cluster/argocd/namespace.yaml

Step 2 — Add Gitea to ArgoCD known hosts

ArgoCD refuses SSH connections to unknown hosts. Pre-populate the known hosts configmap before ArgoCD starts:

ssh-keyscan -t ed25519 gitea.mk-labs.cloud | \
  kubectl create configmap argocd-ssh-known-hosts-cm \
  --namespace argocd \
  --from-file=ssh_known_hosts=/dev/stdin \
  --dry-run=client -o yaml | kubectl apply -f -

Step 3 — Create the Gitea repo secret

This is the only credential that must be manually created. Once ESO is running, secrets will be managed via 1Password. For now, create it directly:

kubectl create secret generic gitea-repo \
  --namespace argocd \
  --from-literal=type=git \
  --from-literal=url=git@gitea.mk-labs.cloud:rblundon/homelab.git \
  --from-file=sshPrivateKey=/home/wed/.ssh/argocd_gitea

kubectl label secret gitea-repo -n argocd \
  argocd.argoproj.io/secret-type=repository

Verify:

kubectl -n argocd get secret gitea-repo

Step 4 — Install ArgoCD via Helm

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 7.8.23 \
  --values cluster/argocd/values.yaml \
  --wait

Wait for all ArgoCD pods to be ready:

kubectl -n argocd get pods --watch

Step 5 — Get the initial admin password

kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath='{.data.password}' | base64 -d; echo

Access the UI via port-forward (ingress-nginx isn't installed yet at this point):

kubectl port-forward svc/argocd-server -n argocd 8080:80

Browse to http://localhost:8080 — login with admin and the password above.


Step 6 — Apply the app-of-apps

This is the second and final manual kubectl apply. It hands control to ArgoCD:

kubectl apply -n argocd -f cluster/argocd/apps-of-apps.yaml

From this point, all changes are made via Git. ArgoCD will begin syncing cluster/platform/ and cluster/applications/ automatically.

Watch the sync:

kubectl -n argocd get applications --watch

Step 7 — Approve CSRs

After nodes join and kubelet starts requesting certs, approve pending CSRs:

kubectl get csr --no-headers | awk '{print $1}' | xargs kubectl certificate approve

Run this periodically until no pending CSRs remain.


Expected platform sync order

Apps sync in wave order via argocd.argoproj.io/sync-wave annotations:

Wave App
0 apps-of-apps (root)
1 cert-manager CRDs
2 cert-manager, external-secrets
3 ingress-nginx
4 external-dns
5+ application workloads

Troubleshooting

ArgoCD can't reach Gitea:

kubectl -n argocd logs deployment/argocd-repo-server | grep -i "error\|ssh"

Check that the gitea-repo secret exists and the known hosts configmap has gitea.mk-labs.cloud.

App stuck in Unknown state:

kubectl -n argocd get application <name> -o yaml | grep -A10 "conditions"

self-reference loop (app syncing itself): Ensure apps-of-apps.yaml uses include: "*/application.yaml" with recurse: true — this prevents ArgoCD from picking up its own manifest.

ArgoCD pruning itself: The argocd namespace Applications must have prune: false. Never enable prune on any Application that manages the argocd namespace.

Helm valueFiles field: The correct field name is valueFiles (plural). valuesFile and valuesFiles are silently ignored — ArgoCD syncs green but your values aren't applied.


Post-bootstrap

Once ingress-nginx and cert-manager are synced:

  • ArgoCD UI available at https://argocd.local.mk-labs.cloud
  • Change the admin password: argocd account update-password
  • Authentik OIDC: uncomment the oidc.config block in values.yaml once the ArgoCD provider is configured in Authentik
  • Migrate gitea-repo secret to ESO once 1Password Connect is running