Cheat notes · Module 10 · Operate with teams
Deployment ordering: hooks, phases and waves
A five-minute review for when you have done this module and want it back in your head. Open the full module for the steps and the lab, or the full text to print.
The idea
Argo CD orders a sync by phase (PreSync, Sync, PostSync), then by wave (lowest first, each healthy before the next), then by kind and name. A PreSync migration that fails stops the release before anything changes.
Remember
- Phases:
PreSync,Sync,PostSync, andSyncFailwhen something fails. (PreDeleteandPostDeleterun around deleting an app.) - Hooks: resources annotated
argocd.argoproj.io/hook: <phase>, usually Jobs. They run when a sync runs and are not part of the compared state, so adding one leaves the app Synced. A delete policy says when to clean them up. - Waves:
argocd.argoproj.io/sync-wave: "-1". Lower waves go first, and Argo CD waits for each wave to be healthy before the next. - Within a wave: by kind (namespaces, CRDs, config, workloads, ...), then alphabetically by name.
- Waves between Applications (app of apps) only wait if Applications report health: add the Lua health check
resource.customizations.health.argoproj.io_Applicationtoargocd-cm. - Migrations must be safe to run twice and backwards compatible: the old pods keep serving while they run.
Pitfalls
- A failed PostSync smoke test marks the sync Failed while the app stays Healthy: the deploy happened, the check after it failed. Read the hook Job's logs.
- Using hooks so an app can wait for its database. Make the app retry; keep hooks for things that run exactly once per release.
- Expecting waves between child Applications to wait without the Application health check.
Commands
argocd app sync APP | Run a sync, and with it the hooks |
argocd app get APP --show-operation | sed -n '/^GROUP/,$p' | The order the last sync applied things in |
kubectl -n NS get jobs | Hook Jobs left behind |
kubectl -n NS logs job/NAME | What a hook did |
grep -H 'sync-wave' apps/*.yaml | Which Applications carry a wave |
The two annotations
# A migration Job: runs before the deploy
metadata:
annotations:
argocd.argoproj.io/hook: PreSync
---
# A ConfigMap: applied before the Deployment that reads it
metadata:
annotations:
argocd.argoproj.io/sync-wave: "-1"
Test yourself
Answer in your head first, then open the answer.
The PreSync migration fails. What happens to the running Deployment?
Nothing. The sync stops before the Sync phase, and the SyncFail hook runs.
Two resources have sync-wave -1 and 0. When does the second start?
Once wave -1 is healthy.
Why does the app of apps need a health check for Applications?
Without it a child Application counts as healthy at once, so waves between Applications do not wait.
You add a hook to the chart. Why does the app stay Synced?
Hooks are not part of the state Argo CD compares. They run on the next sync.
Where module 10 leaves you: Every sync of checkout-dev runs a migration before the deploy and a smoke test after it. You have seen a broken migration leave the old version running, and checkout-dev is back to healthy on 6.7.1.