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-hallhashelm,kubectl, andtalosctlinstalled- 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.configblock invalues.yamlonce the ArgoCD provider is configured in Authentik - Migrate
gitea-reposecret to ESO once 1Password Connect is running