Sync and Drift
Sync is Argo CD making the cluster match git. Drift is the cluster disagreeing with git. This chapter is the knobs that control both.
Manual vs automated sync
By default, sync is manual: Argo CD shows you the diff, you press Sync. Nothing changes until a human says so. This is the right default while learning — and the right choice for production in many teams.
Automated sync applies changes as soon as they're detected:
spec:
syncPolicy:
automated:
prune: true
selfHeal: true
Two sub-options, both worth understanding separately:
prune: true— delete resources that were removed from git. Without it, deleting a manifest from the repo leaves the resource running forever. Prune is how "git is the truth" stays true in the removal direction.selfHeal: true— revert hand-edits back to git state automatically. Thatkubectl scaleexperiment from the last chapter? With self-heal, Argo CD quietly scales it back within minutes. Powerful — and occasionally surprising during incidents, when someone needs a hand-edit to survive.
Sync waves (ordering)
Some resources must exist before others (a namespace
before the deployment in it, a CRD before the custom
resource). Argo CD mostly figures this out, but you can
be explicit with the argocd.argoproj.io/sync-wave
annotation — lower waves sync first:
metadata:
annotations:
argocd.argoproj.io/sync-wave: "1"
Negative waves run before the default (wave 0). Use waves sparingly — every explicit ordering is a dependency you're now maintaining by hand.
Sync options you'll actually use
CreateNamespace=true— let Argo CD create the destination namespace instead of requiring it up front. Set as an annotation or a sync option; nearly everyone wants this on.- Selective sync — in the UI, sync just one resource instead of the whole app. Handy when one deployment is misbehaving and you don't want to touch the rest.
What "OutOfSync" really means
The app controller compares three things: git (desired),
the cluster (live), and its cache. OutOfSync means desired
≠ live. Common causes, in order: someone committed (sync
to catch up), someone hand-edited (sync to revert, or
update git to bless the change), or a controller
misunderstood a field (some fields like status or
auto-generated values need ignore rules — see
Troubleshooting).
The discipline
Automated sync without prune and self-heal is half a GitOps loop — changes flow in, but deletions and drift linger. Manual sync without anyone watching the UI is no loop at all. Pick the combination your team will actually maintain, and make the choice explicit per app. "We didn't decide" always degrades to "nothing syncs and nobody notices."