ArgoCD Sync Waves
Sync waves control the order of resource deployment in ArgoCD. Lower wave numbers deploy first, ensuring dependencies are ready before dependent resources start.
Wave Assignment
| Wave | Resources | Purpose |
|---|---|---|
| -2 | Namespace | Create the namespace first |
| -1 | ServiceAccount, Role, RoleBinding, credential-generator Job, image-versions ConfigMap | RBAC setup and secret generation |
| 0 | PostgreSQL init, S3 credentials sync | Database and storage provisioning |
| 1 | Deployments, Services (backend, frontend, worker) | Application workloads |
| 2 | IngressRoute, Certificate, CronJob, RabbitMQ resources | External access and scheduled tasks |
| 3 | Redis | Cache (deployed after workloads to save resources) |
How It Works
ArgoCD processes resources in wave order:
Wave -2: Create namespace
│
▼
Wave -1: Create RBAC, run credential-generator Job
│ (creates pg, rabbitmq, redis, app-key secrets)
▼
Wave 0: S3 credentials sync Job
│ (waits for CephObjectStoreUser, copies to namespace)
▼
Wave 1: Deploy backend, frontend, worker
│ (all secrets exist at this point)
▼
Wave 2: Create IngressRoutes, TLS certs, CronJobs
│
▼
Wave 3: Deploy Redis
Credential Generator
The credential-generator is a Kubernetes Job that runs at sync-wave -1:
annotations:
argocd.argoproj.io/sync-wave: "-1"
argocd.argoproj.io/hook: Sync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
It creates these secrets (only if they don't exist):
| Secret | How |
|---|---|
{app}-pg-credentials | Connects to PostgreSQL superuser, creates DB + user via psql |
{app}-rabbitmq-credentials | Generates random password, creates import secret in rabbitmq-system |
{app}-app-secrets | Generates Laravel APP_KEY via openssl rand |
{app}-redis-credentials | Generates random password for Redis |
The Job is idempotent — it checks each secret individually and only creates missing ones.
S3 Credentials Sync
A separate Job at sync-wave 0 handles S3 credentials:
annotations:
argocd.argoproj.io/sync-wave: "0"
argocd.argoproj.io/hook: Sync
It waits for the CephObjectStoreUser to be provisioned by Rook-Ceph, then copies the access key and secret key to the application namespace.
Hook Policies
| Annotation | Value | Meaning |
|---|---|---|
argocd.argoproj.io/hook | Sync | Run during every sync |
argocd.argoproj.io/hook-delete-policy | BeforeHookCreation | Delete previous Job before creating new one |
This ensures the credential-generator runs on every sync but doesn't accumulate old Jobs.
Troubleshooting
Pods stuck in CreateContainerConfigError
Cause: A required Secret doesn't exist yet (credential-generator or S3 sync failed).
Fix:
- Check credential-generator Job logs:
kubectl logs job/vecton-admin-credential-generator -n vecton-admin - Check if all secrets exist:
kubectl get secrets -n vecton-admin - If a secret is missing, delete the Job and re-sync: ArgoCD will recreate it
Sync wave ordering issues
If resources deploy out of order:
- Verify
argocd.argoproj.io/sync-waveannotation is set correctly - Remember: ArgoCD processes waves sequentially — wave 1 won't start until wave 0 is healthy
- Hooks (Jobs) in a wave must complete before the next wave starts