Skip to main content

Sync Policies

Manual vs automated

By default, ArgoCD detects drift but does not apply changes automatically. Enable automated sync only where you trust the Git state completely.

syncPolicy:
automated:
prune: true # delete resources removed from Git
selfHeal: true # re-apply if cluster state drifts
prune: true

With pruning enabled, removing a file from Git will delete the corresponding Kubernetes resource. Double-check before enabling in production.

Sync options

syncPolicy:
syncOptions:
- CreateNamespace=true # create destination namespace if missing
- PrunePropagationPolicy=foreground # wait for cascading delete
- PruneLast=true # delete after creating new resources
- Replace=true # use kubectl replace instead of apply
- ServerSideApply=true # use SSA (handles large CRDs)
- RespectIgnoreDifferences=true # apply ignoreFields during sync

Ignore differences

Ignore fields managed by external controllers to prevent constant drift detection:

spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # managed by HPA
- group: ""
kind: Service
jsonPointers:
- /spec/clusterIP # assigned by Kubernetes
- group: autoscaling
kind: HorizontalPodAutoscaler
jqPathExpressions:
- .spec.metrics[] | select(.type == "ContainerResource")

Manual sync triggers

# Sync with pruning
argocd app sync my-app --prune

# Sync a specific resource only
argocd app sync my-app --resource apps:Deployment:api-server

# Dry run
argocd app sync my-app --dry-run

# Force replace (use with caution)
argocd app sync my-app --replace

Refresh

Refresh fetches the latest Git state without applying:

argocd app get my-app --refresh

Force hard refresh (busts the manifest cache):

argocd app get my-app --hard-refresh