Argo CD’s diff process is remarkably flexible, allowing you to tailor how it identifies changes between your desired state (in Git) and your live state (in Kubernetes), but most users only scratch the surface of its capabilities.
Let’s see it in action. Imagine you have a Deployment in Git that looks like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:latest
And in your Kubernetes cluster, you have the same Deployment, but with replicas: 3 and the image is nginx:1.23.3.
When Argo CD runs a diff, it will show you both the replicas and image changes. But what if you want to ignore changes to the replicas count because you have an autoscaler managing it, or you want to ignore the specific nginx tag because you always pull the latest image? This is where customization comes in.
You can control Argo CD’s diff behavior through several mechanisms, primarily via the argocd-cm ConfigMap. The most granular control comes from the resource.customizations setting. This allows you to define rules for specific resource types and even specific fields within those resources.
Here’s how you might configure resource.customizations in your argocd-cm ConfigMap to ignore changes to the replicas field in Deployments and the image field in Pods (which is often what the Deployment template.spec.containers.image translates to):
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations: |
apps/v1/Deployment:
ignoreDifferences: |
- jsonPath: spec.replicas
jqPath: .spec.replicas
v1/Pod:
ignoreDifferences: |
- jsonPath: spec.containers[*].image
jqPath: .spec.containers[].image
After applying this ConfigMap, Argo CD will no longer flag changes to spec.replicas on Deployments or spec.containers[*].image on Pods as drift. The jsonPath is a standard way to select fields in JSON, and jqPath is a similar syntax used by the jq tool, which Argo CD leverages internally for more complex matching.
Beyond resource.customizations, you can also use diff.options in argocd-cm for more global diff settings. For instance, if you want to ignore all annotations that start with deployment.kubernetes.io/, you could add:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
diff.options: |
--ignore-annotation "deployment.kubernetes.io/revision"
--ignore-annotation "deployment.kubernetes.io/etag"
This tells the diffing engine to skip any annotation whose key matches the provided pattern.
A more advanced technique involves using resource.ignoreResourceUpdates to prevent Argo CD from even attempting to diff certain resources entirely, based on their group, kind, and name. This is useful for resources that are managed by other systems and should never be touched by Argo CD.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.ignoreResourceUpdates: |
- group: ""
kind: Event
name: kube-events
- group: apiextensions.k8s.io
kind: CustomResourceDefinition
name: '*' # Ignore all CRDs
Here, we’re ignoring all Kubernetes Events named kube-events and all CustomResourceDefinitions. The name: '*' is a wildcard that matches any resource of the specified group and kind.
The most surprising aspect of Argo CD’s diff customization is its ability to leverage jq expressions directly within resource.customizations for extremely precise filtering. For example, if you only wanted to ignore a specific container’s image within a Pod, you could target it like this:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations: |
v1/Pod:
ignoreDifferences: |
- jsonPath: spec.containers[?(@.name=="my-app")].image
jqPath: '.spec.containers[] | select(.name=="my-app") | .image'
This demonstrates how jsonPath and jqPath can be combined to pinpoint exact fields based on complex conditions, effectively hiding specific pieces of drift from Argo CD’s detection.
Understanding these customization options is key to a smooth Argo CD experience, preventing alert fatigue and ensuring Argo CD focuses on the drift that truly matters for your application’s desired state.
The next step in mastering Argo CD’s diffing will be exploring the use of diff.resourceDeletionProtection to prevent accidental deletions.