Feedback

Chat Icon

GitOps the Hard Way, with Argo CD

Build Real GitOps Pipelines From Empty Clusters to Automated Deploys

Sync Policy: Every Field, Every Sync Option, Every Annotation
48%

Pruning Resources

prune controls whether Argo CD deletes resources that exist in the cluster but no longer exist in Git. With prune: true, removing a Deployment from the repository causes Argo CD to delete that Deployment from the cluster on the next sync. With prune: false (the default), Argo CD does not delete it: the resource keeps running, and the application stays OutOfSync, with the leftover resource shown in the diff as pending pruning.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: todo-app
  namespace: argocd
spec:
  destination:
    namespace: default
    server: https://kubernetes.default.svc
  project: default
  source:
    path: manifests
    repoURL: $GITLAB_URL
    targetRevision: main
  # This is the sync policy
  syncPolicy:
    automated:
      prune: true # <-- enable pruning
      selfHeal: true
      allowEmpty: false
  # End of the sync policy

(i) Pruning is off by default for safety. An accidental deletion in Git should not silently destroy a running resource. Enable it when you want Git to be authoritative for resource existence, not just resource content.

Pruning Exceptions

App-level prune is all-or-nothing. To protect one specific resource from pruning while keeping prune: true for the rest of the application, annotate that resource:

metadata:
  annotations:
    argocd.argoproj.io/sync-options: Prune=false

A Prune sync option set on an individual resource always overrides the prune setting defined on the Application. This is what makes per-resource exceptions work. With this, removing a resource from Git prunes everything except the annotated ones, which keep running.

Pruning With Human Approval

A third option, Prune=confirm, requires manual approval before any pruning happens. It is the middle ground between prune: true (delete freely) and Prune=false (never delete). Useful for resources where an accidental deletion is costly, such as namespaces, PersistentVolumeClaims, or CRDs.

Set it per resource to gate only the dangerous ones:

metadata:
  annotations:
    argocd.argoproj.io/sync-options: Prune=confirm

Or at the application level to gate every prunable resource:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: todo-app
  namespace: argocd
spec:
  destination:
    namespace: default
    server: https://kubernetes.default.svc
  project: default
  source:
    path: manifests
    repoURL: $GITLAB_URL
    targetRevision: main
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: false
    syncOptions:
    - Prune=confirm # <-- gate pruning with confirmation

When a sync needs to prune a resource carrying Prune=confirm, it does not fail and does not skip the resource. The sync operation parks in a Syncing state and waits. It stays there until you approve the deletion through the "Confirm Pruning" button in the UI, the argocd CLI, or by applying the argocd.argoproj.io/deletion-approved annotation to the Application. Until then the sync does not complete.

Pruning Last

You can also configure PruneLast at the Application level or the resource level.

PruneLast controls when pruning happens within a sync, not whether it happens. By default, Argo CD interleaves pruning with applying resources across ordered batches (sync waves).

With PruneLast=true, Argo CD finishes the entire sync first: it applies every new and changed resource, waits for them to become healthy, and only then prunes the resources removed from Git. Pruning runs last, as a final step.

The problem this solves is a deletion landing before its replacement is ready. If you rename a Deployment in Git, Argo CD sees one resource removed and one added; without PruneLast, the old Deployment can be pruned before the new one is healthy, leaving a gap with no running pods. With PruneLast=true, the new resources apply and become healthy first, then the old ones are pruned.

Set it for the whole application:

apiVersion: argoproj.io/v1alpha1
kind:

GitOps the Hard Way, with Argo CD

Build Real GitOps Pipelines From Empty Clusters to Automated Deploys

Enroll now to unlock all content and receive all future updates for free.