ArgoCD’s auto-sync feature, when combined with its self-healing capabilities, allows your GitOps workflow to automatically reconcile the desired state defined in Git with the actual state of your Kubernetes cluster.

Let’s see this in action. Imagine you have a deployment in Git:

# apps/my-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: nginx:1.21.6

And you’ve configured ArgoCD to watch this file and sync it to your cluster.

The Core Problem: Drift

The fundamental problem ArgoCD solves with auto-sync and self-healing is configuration drift. This is when the live state of your applications in Kubernetes diverges from the state defined in your Git repository. Manual reconciliation is tedious, error-prone, and slow.

How Auto-Sync and Self-Healing Work Together

  1. Auto-Sync: When enabled, ArgoCD automatically detects changes in your Git repository and attempts to apply them to your cluster. This means if you update the nginx image tag in apps/my-app.yaml to nginx:1.22.0, ArgoCD will, by default, create a new deployment.

  2. Self-Healing: This is the "magic" part. If something outside of ArgoCD (like a cluster administrator manually scaling down a deployment, or a resource being accidentally deleted) causes the live state to deviate from the desired state after a sync has occurred, ArgoCD will detect this drift and automatically correct it. It brings the cluster back in line with Git.

Enabling Auto-Sync

You can enable auto-sync at the application level within ArgoCD.

Via the ArgoCD UI:

  1. Navigate to your application in the ArgoCD UI.
  2. Click the "Edit" button.
  3. Under the "Sync Policy" section, toggle "Auto-Sync" to "On".
  4. Click "Save".

Via argocd-application-controller arguments (for cluster-wide default):

You can set a default auto-sync policy for all applications by modifying the argocd-application-controller deployment.

  1. Edit the deployment:
    kubectl edit deployment argocd-application-controller -n argocd
    
  2. Add or modify the args section to include:
    spec:
      template:
        spec:
          containers:
          - name: application-controller
            # ... other args
            args:
            - --all-applications-sync=true # This is the key flag
            # ... other args
    
  3. Save the deployment. This will restart the controller, and new applications will inherit this policy. Existing applications will need to be updated or re-synced to pick up the default.

Via Application CRD:

You can set auto-sync directly in your Application custom resource definition:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/your-org/your-repo.git
    targetRevision: HEAD
    path: apps
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  project: default
  syncPolicy:
    automated:
      prune: true # Optional: Automatically delete resources removed from Git
      selfHeal: true # Optional: Enable self-healing

Here, automated.prune: true will remove resources that are no longer defined in Git, and automated.selfHeal: true enables the self-healing mechanism.

Understanding Self-Healing

Self-healing complements auto-sync. Auto-sync ensures that when Git changes, the cluster becomes that state. Self-healing ensures that if the cluster stops being that state, ArgoCD corrects it.

Consider this scenario:

  1. ArgoCD syncs your application, and you have 3 replicas of my-app.
  2. A developer accidentally runs kubectl delete pod my-app-abcdef12-xyz12 in the default namespace.
  3. If selfHeal: true is configured for this application, ArgoCD will detect that the actual number of pods (2) does not match the desired number (3) as defined in the Deployment resource (which ArgoCD knows is supposed to have 3 replicas from Git).
  4. ArgoCD will then trigger a new sync operation to bring the cluster back to the desired state, effectively recreating the deleted pod.

Important Note: Self-healing works by re-applying the desired state. If a resource was deleted, ArgoCD will recreate it. If a resource’s spec was modified outside of Git, ArgoCD will revert it to the spec defined in Git.

The "One More Thing" About Self-Healing

Self-healing is reactive, not preventative. It corrects drift after it occurs. It doesn’t stop someone from making a manual change or deleting a resource. The effectiveness of self-healing relies on ArgoCD’s ability to continuously compare the live state against the desired state and its reconciliation loop running frequently enough to catch deviations. If your reconciliation interval is very long, or if the manual change is very rapid and followed by a Git commit that matches the manual change, self-healing might not behave as you expect. ArgoCD’s reconciliation loop typically runs every few minutes by default.

The Next Step: Resource Pruning

Once you’re comfortable with auto-sync and self-healing, the next logical step is to explore resource pruning. This is also configured within the syncPolicy.automated block (e.g., prune: true in the Application CRD). Pruning ensures that if a resource (like a Service or a Deployment) is removed from your Git repository, ArgoCD will automatically delete it from the cluster, preventing orphaned resources.

Want structured learning?

Take the full Argocd course →