github.com/argoproj/argo-cd/v2@v2.10.5/docs/user-guide/diffing.md (about) 1 # Diffing Customization 2 3 It is possible for an application to be `OutOfSync` even immediately after a successful Sync operation. Some reasons for this might be: 4 5 * There is a bug in the manifest, where it contains extra/unknown fields from the actual K8s spec. These extra fields would get dropped when querying Kubernetes for the live state, 6 resulting in an `OutOfSync` status indicating a missing field was detected. 7 * The sync was performed (with pruning disabled), and there are resources which need to be deleted. 8 * A controller or [mutating webhook](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook) is altering the object after it was 9 submitted to Kubernetes in a manner which contradicts Git. 10 * A Helm chart is using a template function such as [`randAlphaNum`](https://github.com/helm/charts/blob/master/stable/redis/templates/secret.yaml#L16), 11 which generates different data every time `helm template` is invoked. 12 * For Horizontal Pod Autoscaling (HPA) objects, the HPA controller is known to reorder `spec.metrics` 13 in a specific order. See [kubernetes issue #74099](https://github.com/kubernetes/kubernetes/issues/74099). 14 To work around this, you can order `spec.metrics` in Git in the same order that the controller 15 prefers. 16 17 In case it is impossible to fix the upstream issue, Argo CD allows you to optionally ignore differences of problematic resources. 18 The diffing customization can be configured for single or multiple application resources or at a system level. 19 20 ## Application Level Configuration 21 22 Argo CD allows ignoring differences at a specific JSON path, using [RFC6902 JSON patches](https://tools.ietf.org/html/rfc6902) and [JQ path expressions](https://stedolan.github.io/jq/manual/#path(path_expression)). It is also possible to ignore differences from fields owned by specific managers defined in `metadata.managedFields` in live resources. 23 24 The following sample application is configured to ignore differences in `spec.replicas` for all deployments: 25 26 ```yaml 27 spec: 28 ignoreDifferences: 29 - group: apps 30 kind: Deployment 31 jsonPointers: 32 - /spec/replicas 33 ``` 34 35 Note that the `group` field relates to the [Kubernetes API group](https://kubernetes.io/docs/reference/using-api/#api-groups) without the version. 36 The above customization could be narrowed to a resource with the specified name and optional namespace: 37 38 ```yaml 39 spec: 40 ignoreDifferences: 41 - group: apps 42 kind: Deployment 43 name: guestbook 44 namespace: default 45 jsonPointers: 46 - /spec/replicas 47 ``` 48 49 To ignore elements of a list, you can use JQ path expressions to identify list items based on item content: 50 ```yaml 51 spec: 52 ignoreDifferences: 53 - group: apps 54 kind: Deployment 55 jqPathExpressions: 56 - .spec.template.spec.initContainers[] | select(.name == "injected-init-container") 57 ``` 58 59 To ignore fields owned by specific managers defined in your live resources: 60 ```yaml 61 spec: 62 ignoreDifferences: 63 - group: "*" 64 kind: "*" 65 managedFieldsManagers: 66 - kube-controller-manager 67 ``` 68 69 The above configuration will ignore differences from all fields owned by `kube-controller-manager` for all resources belonging to this application. 70 71 If you have a slash `/` in your pointer path, you can use the `~1` character. For example: 72 73 ```yaml 74 spec: 75 ignoreDifferences: 76 - kind: Node 77 jsonPointers: /metadata/labels/node-role.kubernetes.io~1worker 78 ``` 79 80 ## System-Level Configuration 81 82 The comparison of resources with well-known issues can be customized at a system level. Ignored differences can be configured for a specified group and kind 83 in `resource.customizations` key of `argocd-cm` ConfigMap. Following is an example of a customization which ignores the `caBundle` field 84 of a `MutatingWebhookConfiguration` webhooks: 85 86 ```yaml 87 data: 88 resource.customizations.ignoreDifferences.admissionregistration.k8s.io_MutatingWebhookConfiguration: | 89 jqPathExpressions: 90 - '.webhooks[]?.clientConfig.caBundle' 91 ``` 92 93 Resource customization can also be configured to ignore all differences made by a managedField.manager at the system level. The example below shows how to configure Argo CD to ignore changes made by `kube-controller-manager` in `Deployment` resources. 94 95 ```yaml 96 data: 97 resource.customizations.ignoreDifferences.apps_Deployment: | 98 managedFieldsManagers: 99 - kube-controller-manager 100 ``` 101 102 It is possible to configure ignoreDifferences to be applied to all resources in every Application managed by an Argo CD instance. In order to do so, resource customizations can be configured like in the example below: 103 104 ```yaml 105 data: 106 resource.customizations.ignoreDifferences.all: | 107 managedFieldsManagers: 108 - kube-controller-manager 109 jsonPointers: 110 - /spec/replicas 111 ``` 112 113 The `status` field of `CustomResourceDefinitions` is often stored in Git/Helm manifest and should be ignored during diffing. The `ignoreResourceStatusField` setting simplifies 114 handling that edge case: 115 116 ```yaml 117 data: 118 resource.compareoptions: | 119 # disables status field diffing in specified resource types 120 # 'crd' - CustomResourceDefinitions (default) 121 # 'all' - all resources 122 # 'none' - disabled 123 ignoreResourceStatusField: crd 124 ``` 125 126 By default `status` field is ignored during diffing for `CustomResourceDefinition` resource. The behavior can be extended to all resources using `all` value or disabled using `none`. 127 128 ### Ignoring RBAC changes made by AggregateRoles 129 130 If you are using [Aggregated ClusterRoles](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles) and don't want Argo CD to detect the `rules` changes as drift, you can set `resource.compareoptions.ignoreAggregatedRoles: true`. Then Argo CD will no longer detect these changes as an event that requires syncing. 131 132 ```yaml 133 apiVersion: v1 134 kind: ConfigMap 135 metadata: 136 name: argocd-cm 137 data: 138 resource.compareoptions: | 139 # disables status field diffing in specified resource types 140 ignoreAggregatedRoles: true 141 ``` 142 143 ## Known Kubernetes types in CRDs (Resource limits, Volume mounts etc) 144 145 Some CRDs are re-using data structures defined in the Kubernetes source base and therefore inheriting custom 146 JSON/YAML marshaling. Custom marshalers might serialize CRDs in a slightly different format that causes false 147 positives during drift detection. 148 149 A typical example is the `argoproj.io/Rollout` CRD that re-using `core/v1/PodSpec` data structure. Pod resource requests 150 might be reformatted by the custom marshaller of `IntOrString` data type: 151 152 from: 153 ```yaml 154 resources: 155 requests: 156 cpu: 100m 157 ``` 158 159 to: 160 ```yaml 161 resources: 162 requests: 163 cpu: 0.1 164 ``` 165 166 The solution is to specify which CRDs fields are using built-in Kubernetes types in the `resource.customizations` 167 section of `argocd-cm` ConfigMap: 168 169 ```yaml 170 apiVersion: v1 171 kind: ConfigMap 172 metadata: 173 name: argocd-cm 174 namespace: argocd 175 labels: 176 app.kubernetes.io/name: argocd-cm 177 app.kubernetes.io/part-of: argocd 178 data: 179 resource.customizations.knownTypeFields.argoproj.io_Rollout: | 180 - field: spec.template.spec 181 type: core/v1/PodSpec 182 ``` 183 184 The list of supported Kubernetes types is available in [diffing_known_types.txt](https://raw.githubusercontent.com/argoproj/argo-cd/master/util/argo/normalizers/diffing_known_types.txt) and additionally: 185 186 * `core/Quantity` 187 * `meta/v1/duration`