By default an Application is manual: Argo CD shows OutOfSync and waits for someone to press Sync. An automated policy makes Argo CD apply every new commit on its own:
spec:
syncPolicy:
automated:
prune: true # delete objects that were removed from Git
selfHeal: true # revert changes made directly in the cluster
allowEmpty: false # never sync to "zero resources" by mistake
syncOptions:
- CreateNamespace=true
- PruneLast=true
- ApplyOutOfSyncOnly=true
retry:
limit: 5
backoff: { duration: 10s, factor: 2, maxDuration: 3m }
| Setting | Off (default) | On |
|---|---|---|
automated |
You sync by hand | New commits are applied within the poll interval or on webhook |
prune |
Removed objects stay running, marked for pruning | Removed objects are deleted |
selfHeal |
Manual kubectl edit shows OutOfSync and stays |
Drift is reverted (after a short delay) |
allowEmpty |
Refuses to sync if the source renders nothing | Allows deleting everything (dangerous) |
Prune and self-heal are off by default because they delete or overwrite things. Turn them on deliberately — usually yes for dev and for mature prod setups, where Git really is the only way to change things.
argocd app set shop-api-dev --sync-policy automated --auto-prune --self-heal
argocd app set shop-api-prod --sync-policy none # back to manual
Useful sync options
| Option | Use it when |
|---|---|
CreateNamespace=true |
The destination namespace may not exist yet |
PruneLast=true |
Delete old objects only after the new ones are healthy |
ApplyOutOfSyncOnly=true |
Large apps: apply only the objects that changed |
ServerSideApply=true |
Very large objects (big CRDs) or fields owned by several managers |
Replace=true |
An object cannot be patched and must be replaced (use rarely) |
Prune=false (as an annotation on one object) |
Never delete this object, even with prune on |
Delete=false (annotation) |
Keep this object when the Application is deleted, for example a PVC |
Per-object options go in the annotation argocd.argoproj.io/sync-options, for example Prune=false.
Retry and failure
A sync can fail (an admission webhook rejects a Pod, a CRD is not ready yet). retry tries again with back-off. Without automated sync a failed sync just stays failed; with it, Argo CD retries on the next change or by the retry policy.
Sync windows
An AppProject can define sync windows: for example "deny automated syncs to prod on Friday 17:00–Monday 08:00". Manual syncs can be allowed or blocked inside a window.
Watch out: with selfHeal on, an on-call engineer's emergency kubectl scale is undone within seconds. The emergency path is a commit (or temporarily turning self-heal off, written down in the incident).