ArgoCD Sync Policies: A Practical Guide

What Is ArgoCD Sync Policy? 

ArgoCD Sync Policy is an important feature of ArgoCD, a GitOps tool which manages the synchronization of applications deployed in a Kubernetes environment with their corresponding configurations stored in a Git repository. 

This policy defines how and when ArgoCD should apply changes from the repository to the Kubernetes cluster. Essentially, it’s a set of rules and behaviors that control the update process of your applications, ensuring that your live applications reflect the desired state defined in your Git repository. It plays a critical role in maintaining consistency, enforcing version control, and automating deployment processes in a Kubernetes environment managed by ArgoCD.

Types of Synchronization in ArgoCD 

Manual: Sync Trigger by Operator

In manual sync, the synchronization between the Git repository and the Kubernetes cluster is initiated manually by an operator. This approach allows for a high level of control over when changes are applied, making it suitable for environments where changes need to be thoroughly reviewed or tested before deployment. 

Manual sync is often used in staging or production environments where stability and control are paramount. Operators can review the proposed changes in the Git repository and manually trigger a sync operation to apply these changes to the cluster, ensuring that they have the opportunity to intervene or halt the process if needed.

Automatic Sync Triggered in Response to Cluster Changes

Automatic synchronization is a feature where ArgoCD continuously monitors the Git repository for any changes and automatically applies these changes to the Kubernetes cluster. 

This mode is suitable for environments where rapid iteration and continuous deployment are required. It minimizes human intervention, ensuring that cluster state is always up-to-date with the latest configurations in the Git repository.

The Role of Sync Policies

Sync policies in ArgoCD serve two primary functions: 

  • Determining how ArgoCD reacts to changes in the Git repository: Whether to automatically apply these changes, wait for manual intervention, or follow a specific set of rules before syncing. 
  • Which safety measures to apply: Sync policies can incorporate safety measures like preventing unintended deletions or modifications, ensuring that automated processes do not compromise the stability and security of the Kubernetes cluster.

How to Set a Sync Policy

If you are creating the application from an application manifest, you can specify a sync policy in the spec:syncPolicy attribute:

spec:
  syncPolicy:
    automated: {}

Another way to set a sync policy is via the Argo CD CLI:

argocd app set <APPNAME> --sync-policy automated

There are several additional options you can set, which we will cover below.

Types of ArgoCD Sync Policies 

Enabling Automatic Self-Healing

ArgoCD doesn’t automatically sync changes made to the live cluster by default. You can configure the system to automatically sync differences in the live cluster state and the Git-defined state.

Here is how to do this by setting the selfHeal value of the automated sync policy to true:

spec:
  syncPolicy:
    automated:
      selfHeal: true

Alternatively, you can run this CLI command:

argocd app set <APPNAME> --self-heal

Server-Side Apply

By default, ArgoCD makes use of the kubectl apply command to apply Git-stored configurations. This client-side operation depends on the kubectl.kubernetes.io/last-applied-configuration annotation to keep track of the prior resource state. 

However, you can configure ArgoCD to use Kubernetes server-side apply. This is useful in the following cases:

  • The resource is larger than the 262,144 bytes allowed by annotations. In this scenario, server-side apply can circumvent this limitation as annotations are not utilized.
  • Partial modification of resources within the cluster which aren’t fully managed by ArgoCD.
  • You prefer a more declarative way of tracking field management as opposed to tracking the user’s last applied state.

If ServerSideApply=true is set, Argo CD will use the kubectl apply --server-side command.

This option can be enabled at the application level as shown below:

apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  syncPolicy:
    syncOptions:
    - ServerSideApply=true

To enable ServerSideApply on an individual resource, use the sync-option annotation:

metadata:
  annotations:
    argocd.argoproj.io/sync-options: ServerSideApply=true

Automatic Pruning

As a default safety feature, automated sync in ArgoCD doesn’t delete resources that have been removed from the Git repository. These resources then need to be ‘pruned’. Manual sync (with Pruning checked) can perform this pruning, removing these resources from the Kubernetes cluster. 

Alternatively, automatic pruning can be incorporated as part of the automated sync process by setting the prune option to true in the automated sync policy:

spec:
  syncPolicy:
    automated:
      prune: true

Or, alternatively, by running this CLI command:

argocd app set <APPNAME> --auto-prune

Automatic Pruning with Allow-Empty

By default, to protect from automation or human errors, automated sync with prune will not execute if no target resources exist. This is to prevent applications from having empty resources. To allow applications to have empty resources, set the allowEmpty option to true in the automated sync policy:

spec:
  syncPolicy:
    automated:
      prune: true
      allowEmpty: true

Alternatively, run this CLI command:

argocd app set <APPNAME> --allow-empty

Additional Sync Policy Options 

Turning Off Kubectl Validation

Certain types of objects, like those using RawExtension such as ServiceCatalog, require the use of kubectl apply with the --validate=false flag. This can be achieved by using the following annotation:

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

If you want to exclude an entire class of objects universally, you can adjust resource.customizations in the system-level configuration.

Bypassing Dry Run for New Custom Resource Types

For custom resource definitions (CRDs) not yet registered in the cluster, you generally have two options:

  • CRD manifest synchronizes simultaneously: In this scenario, Argo CD automatically skips the dry run. Applying the CRD enables resource creation.
  • CRD is separate from the sync: It can be created elsewhere, for example through a cluster controller.

To ignore dry run for missing resources, use the following annotation:

metadata:
  annotations:
    argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true

The dry run continues as usual if the CRD already exists in the cluster.

Preventing Resource Deletion

To keep resources (like Persistent Volume Claims) after their application has been deleted, you can use the following annotation. It prevents the resources from being deleted together with the application:

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

Using Selective Sync

By default, Argo CD applies all objects in an application during an auto sync. If your application has thousands of objects, this demands significant time and strains the API server. The selective sync option lets Argo CD sync only out-of-sync resources.

You can enable this feature in two ways. In the manifest, by adding ApplyOutOfSyncOnly=true:

apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  syncPolicy:
    syncOptions:
    - ApplyOutOfSyncOnly=true

The other way is via the ArgoCD CLI, as follows:

$ argocd app set guestbook --sync-option ApplyOutOfSyncOnly=true

Modifying Resources Prune Deletion Propagation Policy

By default, unnecessary resources undergo pruning using foreground deletion policy. To control the propagation policy, use the PrunePropagationPolicy sync option. The available policies are background, foreground, and orphan. Here is how to set a propagation policy:

apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  syncPolicy:
    syncOptions:
    - PrunePropagationPolicy=foreground

Postponing Pruning

This feature lets resource pruning occur last in a sync operation, after deploying other resources and their successful operation, and after completing all other wave activities.

apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  syncPolicy:
    syncOptions:
    - PruneLast=true

You can also configure this at an individual resource level:

metadata:
  annotations:
    argocd.argoproj.io/sync-options: PruneLast=true

Replacing Resources Rather Than Updating

Argo CD typically executes kubectl apply to apply Git-stored configuration. This may not suit all scenarios, for example if the resource spec is too large to fit into the kubectl.kubernetes.io/last-applied-configuration annotation. In such scenarios, use the Replace=true sync option:

apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  syncPolicy:
    syncOptions:
    - Replace=true

With Replace=true set, Argo CD uses kubectl replace or kubectl create to apply changes.

This can also be configured at the individual resource level:

metadata:
  annotations:
    argocd.argoproj.io/sync-options: Replace=true

Failing Upon Detecting a Shared Resource

By default, ArgoCD applies all the manifests, even if resources are already applied by a different application. However, setting the FailOnSharedResource sync option lets Argo CD fail the sync upon finding a resource, already applied by a different application:

apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  syncPolicy:
    syncOptions:
    - FailOnSharedResource=true

Respecting Difference Configurations

RespectIgnoreDifferences=true is a sync option that allows ArgoCD to also consider spec.ignoreDifferences configurations during sync. Typically, Argo CD doesn’t use the ignoreDifferences config during the sync stage.

This example shows how Argo CD can be set up to disregard the spec.replicas field from the desired state during the sync stage:

apiVersion: argoproj.io/v1alpha1
kind: Application
spec:

  ignoreDifferences:
  - group: "apps"
    kind: "Deployment"
    jsonPointers:
    - /spec/replicas

  syncPolicy:
    syncOptions:
    - RespectIgnoreDifferences=true

Creating Namespace

The CreateNamespace=true sync option allows Argo CD to create the namespace, as given in spec.destination.namespace, if it doesn’t exist.

Be sure to record the namespace to be created in the spec.destination.namespace field of the Application resource. You’ll need to match the metadata.namespace field in the Application’s child manifests to this value.

Learn More in the Manning Report: GitOps with ArgoCD

Software teams that adopt GitOps deploy more often, have fewer regressions and recover from failures more quickly. GitOps works, as evidenced by many success stories we at Codefresh have seen first hand. Learn more about GitOps in an in-depth guide by Alexander Matyushentsev, one of the founders of the Argo project. Argo is the world’s fastest growing and most popular open-source GitOps tool in the world today. Users love it, and that is the reason Codefresh has based its enterprise platform on the beloved tool.


Learn to practice GitOps with ArgoCD in the Manning Report: GitOps with ArgoCD

Ready to Get Started?

Deploy more and fail less with Codefresh and Argo