github.com/argoproj/argo-cd/v2@v2.10.9/docs/operator-manual/applicationset/Controlling-Resource-Modification.md (about) 1 # Controlling if/when the ApplicationSet controller modifies `Application` resources 2 3 The ApplicationSet controller supports a number of settings that limit the ability of the controller to make changes to generated Applications, for example, preventing the controller from deleting child Applications. 4 5 These settings allow you to exert control over when, and how, changes are made to your Applications, and to their corresponding cluster resources (`Deployments`, `Services`, etc). 6 7 Here are some of the controller settings that may be modified to alter the ApplicationSet controller's resource-handling behaviour. 8 9 ## Dry run: prevent ApplicationSet from creating, modifying, or deleting all Applications 10 11 To prevent the ApplicationSet controller from creating, modifying, or deleting any `Application` resources, you may enable `dry-run` mode. This essentially switches the controller into a "read only" mode, where the controller Reconcile loop will run, but no resources will be modified. 12 13 To enable dry-run, add `--dryrun true` to the ApplicationSet Deployment's container launch parameters. 14 15 See 'How to modify ApplicationSet container parameters' below for detailed steps on how to add this parameter to the controller. 16 17 ## Managed Applications modification Policies 18 19 The ApplicationSet controller supports a parameter `--policy`, which is specified on launch (within the controller Deployment container), and which restricts what types of modifications will be made to managed Argo CD `Application` resources. 20 21 The `--policy` parameter takes four values: `sync`, `create-only`, `create-delete`, and `create-update`. (`sync` is the default, which is used if the `--policy` parameter is not specified; the other policies are described below). 22 23 It is also possible to set this policy per ApplicationSet. 24 25 ```yaml 26 apiVersion: argoproj.io/v1alpha1 27 kind: ApplicationSet 28 spec: 29 # (...) 30 syncPolicy: 31 applicationsSync: create-only # create-update, create-delete sync 32 33 ``` 34 35 - Policy `create-only`: Prevents ApplicationSet controller from modifying or deleting Applications. Prevents Application controller from deleting Applications according to [ownerReferences](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/). 36 - Policy `create-update`: Prevents ApplicationSet controller from deleting Applications. Update is allowed. Prevents Application controller from deleting Applications according to [ownerReferences](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/). 37 - Policy `create-delete`: Prevents ApplicationSet controller from modifying Applications. Delete is allowed. 38 - Policy `sync`: Update and Delete are allowed. 39 40 If the controller parameter `--policy` is set, it takes precedence on the field `applicationsSync`. It is possible to allow per ApplicationSet sync policy by setting variable `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE` to argocd-cmd-params-cm `applicationsetcontroller.enable.policy.override` or directly with controller parameter `--enable-policy-override` (default to `false`). 41 42 ### Controller parameter 43 44 To allow the ApplicationSet controller to *create* `Application` resources, but prevent any further modification, such as deletion, or modification of Application fields, add this parameter in the ApplicationSet controller: 45 ``` 46 --policy create-only 47 ``` 48 49 At ApplicationSet level 50 51 ```yaml 52 apiVersion: argoproj.io/v1alpha1 53 kind: ApplicationSet 54 spec: 55 # (...) 56 syncPolicy: 57 applicationsSync: create-only 58 ``` 59 60 ## Policy - `create-update`: Prevent ApplicationSet controller from deleting Applications 61 62 To allow the ApplicationSet controller to create or modify `Application` resources, but prevent Applications from being deleted, add the following parameter to the ApplicationSet controller `Deployment`: 63 ``` 64 --policy create-update 65 ``` 66 67 This may be useful to users looking for additional protection against deletion of the Applications generated by the controller. 68 69 At ApplicationSet level 70 71 ```yaml 72 apiVersion: argoproj.io/v1alpha1 73 kind: ApplicationSet 74 spec: 75 # (...) 76 syncPolicy: 77 applicationsSync: create-update 78 ``` 79 80 ## Ignore certain changes to Applications 81 82 The ApplicationSet spec includes an `ignoreApplicationDifferences` field, which allows you to specify which fields of 83 the ApplicationSet should be ignored when comparing Applications. 84 85 The field supports multiple ignore rules. Each ignore rule may specify a list of either `jsonPointers` or 86 `jqPathExpressions` to ignore. 87 88 You may optionally also specify a `name` to apply the ignore rule to a specific Application, or omit the `name` to apply 89 the ignore rule to all Applications. 90 91 ```yaml 92 apiVersion: argoproj.io/v1alpha1 93 kind: ApplicationSet 94 spec: 95 ignoreApplicationDifferences: 96 - jsonPointers: 97 - /spec/source/targetRevision 98 - name: some-app 99 jqPathExpressions: 100 - .spec.source.helm.values 101 ``` 102 103 ### Allow temporarily toggling auto-sync 104 105 One of the most common use cases for ignoring differences is to allow temporarily toggling auto-sync for an Application. 106 107 For example, if you have an ApplicationSet that is configured to automatically sync Applications, you may want to temporarily 108 disable auto-sync for a specific Application. You can do this by adding an ignore rule for the `spec.syncPolicy.automated` field. 109 110 ```yaml 111 apiVersion: argoproj.io/v1alpha1 112 kind: ApplicationSet 113 spec: 114 ignoreApplicationDifferences: 115 - jsonPointers: 116 - /spec/syncPolicy 117 ``` 118 119 ### Limitations of `ignoreApplicationDifferences` 120 121 When an ApplicationSet is reconciled, the controller will compare the ApplicationSet spec with the spec of each Application 122 that it manages. If there are any differences, the controller will generate a patch to update the Application to match the 123 ApplicationSet spec. 124 125 The generated patch is a MergePatch. According to the MergePatch documentation, "existing lists will be completely 126 replaced by new lists" when there is a change to the list. 127 128 This limits the effectiveness of `ignoreApplicationDifferences` when the ignored field is in a list. For example, if you 129 have an application with multiple sources, and you want to ignore changes to the `targetRevision` of one of the sources, 130 changes in other fields or in other sources will cause the entire `sources` list to be replaced, and the `targetRevision` 131 field will be reset to the value defined in the ApplicationSet. 132 133 For example, consider this ApplicationSet: 134 135 ```yaml 136 apiVersion: argoproj.io/v1alpha1 137 kind: ApplicationSet 138 spec: 139 ignoreApplicationDifferences: 140 - jqPathExpressions: 141 - .spec.sources[] | select(.repoURL == "https://git.example.com/org/repo1").targetRevision 142 template: 143 spec: 144 sources: 145 - repoURL: https://git.example.com/org/repo1 146 targetRevision: main 147 - repoURL: https://git.example.com/org/repo2 148 targetRevision: main 149 ``` 150 151 You can freely change the `targetRevision` of the `repo1` source, and the ApplicationSet controller will not overwrite 152 your change. 153 154 ```yaml 155 apiVersion: argoproj.io/v1alpha1 156 kind: Application 157 spec: 158 sources: 159 - repoURL: https://git.example.com/org/repo1 160 targetRevision: fix/bug-123 161 - repoURL: https://git.example.com/org/repo2 162 targetRevision: main 163 ``` 164 165 However, if you change the `targetRevision` of the `repo2` source, the ApplicationSet controller will overwrite the entire 166 `sources` field. 167 168 ```yaml 169 apiVersion: argoproj.io/v1alpha1 170 kind: Application 171 spec: 172 sources: 173 - repoURL: https://git.example.com/org/repo1 174 targetRevision: main 175 - repoURL: https://git.example.com/org/repo2 176 targetRevision: main 177 ``` 178 179 !!! note 180 [Future improvements](https://github.com/argoproj/argo-cd/issues/15975) to the ApplicationSet controller may 181 eliminate this problem. For example, the `ref` field might be made a merge key, allowing the ApplicationSet 182 controller to generate and use a StrategicMergePatch instead of a MergePatch. You could then target a specific 183 source by `ref`, ignore changes to a field in that source, and changes to other sources would not cause the ignored 184 field to be overwritten. 185 186 ## Prevent an `Application`'s child resources from being deleted, when the parent Application is deleted 187 188 By default, when an `Application` resource is deleted by the ApplicationSet controller, all of the child resources of the Application will be deleted as well (such as, all of the Application's `Deployments`, `Services`, etc). 189 190 To prevent an Application's child resources from being deleted when the parent Application is deleted, add the `preserveResourcesOnDeletion: true` field to the `syncPolicy` of the ApplicationSet: 191 ```yaml 192 apiVersion: argoproj.io/v1alpha1 193 kind: ApplicationSet 194 spec: 195 # (...) 196 syncPolicy: 197 preserveResourcesOnDeletion: true 198 ``` 199 200 More information on the specific behaviour of `preserveResourcesOnDeletion`, and deletion in ApplicationSet controller and Argo CD in general, can be found on the [Application Deletion](Application-Deletion.md) page. 201 202 203 ## Prevent an Application's child resources from being modified 204 205 Changes made to the ApplicationSet will propagate to the Applications managed by the ApplicationSet, and then Argo CD will propagate the Application changes to the underlying cluster resources (as per [Argo CD Integration](Argo-CD-Integration.md)). 206 207 The propagation of Application changes to the cluster is managed by the [automated sync settings](../../user-guide/auto_sync.md), which are referenced in the ApplicationSet `template` field: 208 209 - `spec.template.syncPolicy.automated`: If enabled, changes to Applications will automatically propagate to the cluster resources of the cluster. 210 - Unset this within the ApplicationSet template to 'pause' updates to cluster resources managed by the `Application` resource. 211 - `spec.template.syncPolicy.automated.prune`: By default, Automated sync will not delete resources when Argo CD detects the resource is no longer defined in Git. 212 - For extra safety, set this to false to prevent unexpected changes to the backing Git repository from affecting cluster resources. 213 214 215 ## How to modify ApplicationSet container launch parameters 216 217 There are a couple of ways to modify the ApplicationSet container parameters, so as to enable the above settings. 218 219 ### A) Use `kubectl edit` to modify the deployment on the cluster 220 221 Edit the applicationset-controller `Deployment` resource on the cluster: 222 ``` 223 kubectl edit deployment/argocd-applicationset-controller -n argocd 224 ``` 225 226 Locate the `.spec.template.spec.containers[0].command` field, and add the required parameter(s): 227 ```yaml 228 spec: 229 # (...) 230 template: 231 # (...) 232 spec: 233 containers: 234 - command: 235 - entrypoint.sh 236 - argocd-applicationset-controller 237 # Insert new parameters here, for example: 238 # --policy create-only 239 # (...) 240 ``` 241 242 Save and exit the editor. Wait for a new `Pod` to start containing the updated parameters. 243 244 ### Or, B) Edit the `install.yaml` manifest for the ApplicationSet installation 245 246 Rather than directly editing the cluster resource, you may instead choose to modify the installation YAML that is used to install the ApplicationSet controller: 247 248 Applicable for applicationset versions less than 0.4.0. 249 ```bash 250 # Clone the repository 251 252 git clone https://github.com/argoproj/applicationset 253 254 # Checkout the version that corresponds to the one you have installed. 255 git checkout "(version of applicationset)" 256 # example: git checkout "0.1.0" 257 258 cd applicationset/manifests 259 260 # open 'install.yaml' in a text editor, make the same modifications to Deployment 261 # as described in the previous section. 262 263 # Apply the change to the cluster 264 kubectl apply -n argocd -f install.yaml 265 ``` 266 267 ## Preserving changes made to an Applications annotations and labels 268 269 !!! note 270 The same behavior can be achieved on a per-app basis using the [`ignoreApplicationDifferences`](#ignore-certain-changes-to-applications) 271 feature described above. However, preserved fields may be configured globally, a feature that is not yet available 272 for `ignoreApplicationDifferences`. 273 274 It is common practice in Kubernetes to store state in annotations, operators will often make use of this. To allow for this, it is possible to configure a list of annotations that the ApplicationSet should preserve when reconciling. 275 276 For example, imagine that we have an Application created from an ApplicationSet, but a custom annotation and label has since been added (to the Application) that does not exist in the `ApplicationSet` resource: 277 ```yaml 278 apiVersion: argoproj.io/v1alpha1 279 kind: Application 280 metadata: 281 # This annotation and label exists only on this Application, and not in 282 # the parent ApplicationSet template: 283 annotations: 284 my-custom-annotation: some-value 285 labels: 286 my-custom-label: some-value 287 spec: 288 # (...) 289 ``` 290 291 To preserve this annotation and label we can use the `preservedFields` property of the `ApplicationSet` like so: 292 ```yaml 293 apiVersion: argoproj.io/v1alpha1 294 kind: ApplicationSet 295 spec: 296 # (...) 297 preservedFields: 298 annotations: ["my-custom-annotation"] 299 labels: ["my-custom-label"] 300 ``` 301 302 The ApplicationSet controller will leave this annotation and label as-is when reconciling, even though it is not defined in the metadata of the ApplicationSet itself. 303 304 By default, the Argo CD notifications and the Argo CD refresh type annotations are also preserved. 305 306 !!!note 307 One can also set global preserved fields for the controller by passing a comma separated list of annotations and labels to 308 `ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_ANNOTATIONS` and `ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_LABELS` respectively. 309 310 ## Debugging unexpected changes to Applications 311 312 When the ApplicationSet controller makes a change to an application, it logs the patch at the debug level. To see these 313 logs, set the log level to debug in the `argocd-cmd-params-cm` ConfigMap in the `argocd` namespace: 314 315 ```yaml 316 apiVersion: v1 317 kind: ConfigMap 318 metadata: 319 name: argocd-cmd-params-cm 320 namespace: argocd 321 data: 322 applicationsetcontroller.log.level: debug 323 ```