activate-gitops.sh is intentionally the final step — it applies a single file (k8s/apps/root.yaml) and then gets out of the way. After that, Git is the sole source of truth and ArgoCD drives everything. No more imperative kubectl apply.
01 What activate-gitops.sh does
$ ./provision/activate-gitops.sh
The script does three things:
- Preflight checks — verifies
kubectlreaches the cluster, ArgoCD is installed, and Longhorn is installed. Fails fast if either is missing. - Applies
k8s/apps/root.yaml— this creates the rootApplicationin ArgoCD. The root app watchesk8s/apps/in the repo and creates a child Application for every YAML file it finds there. - Prints instructions — how to watch the rollout, how to get the initial admin password, and the ArgoCD UI URL.
rebuild.sh. When the root app deploys k8s/apps/argocd.yaml and k8s/apps/longhorn.yaml, ArgoCD "adopts" those installs — it compares the live state to the Helm values in k8s/components/*/ and finds zero diff, because the bootstrap used the same source. No re-install, no downtime.02 Sync-wave sequence
ArgoCD deploys apps in wave order. Within a wave, it waits for all resources to be healthy before advancing to the next wave. The full sequence from activation to fully healthy cluster:
| Wave | Applications | Why this order |
|---|---|---|
| −1 | vault |
Must be unsealed before ESO (wave 1) can read secrets. PVC reattachment is the bottleneck — ~4–5 min after pod start. |
| 0 | argocd, longhorn |
Platform adoption. ArgoCD adopts itself (no diff). Longhorn adopts its bootstrapped install. |
| 1 | ingress-nginx, cert-manager, external-secrets |
Ingress and TLS must be ready before apps need HTTPS. ESO must connect to Vault before apps need secrets. |
| 2 | monitor, db, auth, cloud, immich, whoami, aly |
User-facing apps. By now ingress, TLS, secrets, and storage are all healthy. |
03 Vault unseal after activation
Vault's pod starts sealed. The vault-auto-unseal CronJob (deployed as part of the vault Application) runs every minute. It checks TCP port 8200 with nc, then runs timeout 5 vault status. Exit code 2 = sealed → unseals. The Longhorn PVC reattachment is the bottleneck — expect Vault to unseal 4–5 minutes after the pod starts.
Once Vault is unsealed, the eso-recovery CronJob detects that the ClusterSecretStore is degraded and restarts the ESO deployments to clear backoff. ESO reconnects, syncs all ExternalSecret resources, and apps get their secrets. Total time from activation to fully healthy: ~6 minutes.
04 Watching the rollout
# watch all Applications converge to Synced/Healthy
$ kubectl get applications -n argocd -w
# watch Vault unseal (look for "Vault is unsealed" in logs)
$ kubectl logs -n security -l job-name --tail=20 -f
# check ClusterSecretStore status
$ kubectl get clustersecretstore k8s-secrets
# initial ArgoCD admin password (rotate after first login)
$ kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath='{.data.password}' | base64 -d; echo
# open ArgoCD before ingress is live
$ kubectl port-forward -n argocd svc/argocd-server 8080:80
# → http://localhost:8080 username: admin
# once ingress-nginx syncs, access via HTTPS
# → https://argo.in.alybadawy.com
05 Post-activation checklist
- Wait for all 14 Applications to show
Synced+Healthyin ArgoCD. - Confirm Vault is unsealed:
kubectl exec -n security vault-0 -- vault status. - Confirm ESO is connected:
kubectl get clustersecretstore k8s-secretsshould showValid. - Open argo.in.alybadawy.com and rotate the admin password.
- Open grafana.in.alybadawy.com and verify metrics are flowing.
- Delete the initial admin secret:
kubectl delete secret argocd-initial-admin-secret -n argocd.