github.com/argoproj/argo-cd/v3@v3.2.1/docs/proposals/deletion-strategy-progressive-sync.md (about) 1 --- 2 title: Neat-enhancement-idea 3 authors: 4 - "@ranakan19" # Authors' github accounts here. 5 sponsors: 6 - TBD # List all interested parties here. 7 reviewers: 8 - TBD 9 approvers: 10 - TBD 11 12 creation-date: 2025-04-30 13 last-updated: 2025-05-01 14 --- 15 16 # Deletion Strategy for Progressive Sync 17 18 This proposal is building upon the ideas presented in https://github.com/argoproj/argo-cd/pull/14892 to introduce 19 deletion strategy for progressive sync. While the original proposal laid the groundwork, this proposal extends to address 20 some unanswered sections and changes implementation details. 21 22 Introduce a new functionality of ArgoCD ProgressiveSync that will allow users to configure order 23 of deletion for applicationSet's deployed applications. The deletion strategies can be: 24 25 - AllAtOnce (current behaviour - where all applications are deleted in no particular order without waiting for an application 26 to be deleted; can be the default value) 27 - reverse ( delete applications in the reverse order of deployment, configured in progressiveSync. This expects the 28 rollingSync field to have a specified order and implements deletion in the reverse order specified. 29 Waits for one application to be fully deleted before moving onto the next application.) 30 31 ## Open Questions [optional] 32 33 The original proposal mentions another strategy - `custom` wherein the user can provide a specific order of deletion. 34 Is such a usecase needed? 35 36 37 ## Summary 38 39 This feature can extend the application dependency from deployment to deletion as well. Ability to provide deletion order 40 can complete the ProgressiveSync feature. 41 42 ## Motivation 43 44 Current deletion/removal strategy which ArgoCD use works fine if there aren't any dependencies between the different applications. 45 However, it does not work when there are dependencies between the applications. This was noticed when some kubernetes core services 46 were deployed in specific order and to be removed in reverse order. 47 48 ### Goals 49 50 Following goals should be achieved in order to conclude this proposal: 51 1. Deletion strategy `AllAtOnce` as default value - deletes all applications at once as the current behavior of deletion. 52 2. Deletion strategy `Reverse` lets applications be deleted in the reverse order of the steps configured in RollingSync strategy. 53 54 ### Non-Goals 55 56 custom deletion strategy - this will be a separate goal if there is enough demand for it. 57 58 ## Proposal 59 60 Ability to provide configuration related to the deletion/removal process when progressive sync is used. Implementation detail provides 61 two options of introducing this field in ApplicationSet. The following use cases assumes Option 1 for the yaml file examples. 62 63 ### Use cases 64 65 Add a list of detailed use cases this enhancement intends to take care of. 66 67 #### AllAtOnce deletionStrategy: 68 ```yaml 69 apiVersion: argoproj.io/v1alpha1 70 kind: ApplicationSet 71 metadata: 72 name: pricelist 73 namespace: argocd 74 spec: 75 generators: 76 - list: 77 elements: 78 - srv: config 79 path: applicationsets/rollingsync/apps/pricelist-config 80 - srv: db 81 path: applicationsets/rollingsync/apps/pricelist-db 82 - srv: frontend 83 path: applicationsets/rollingsync/apps/pricelist-frontend 84 strategy: 85 type: RollingSync 86 rollingSync: 87 steps: 88 - matchExpressions: 89 - key: pricelist-component # the "key" is based on the label (below as "pricelist-component: {{srv}}") 90 operator: In 91 values: 92 - config 93 - matchExpressions: 94 - key: pricelist-component 95 operator: In 96 values: 97 - db 98 - matchExpressions: 99 - key: pricelist-component 100 operator: In 101 values: 102 - frontend 103 ### Deletion configuration ### 104 deletionOrder: AllAtOnce # available options to be AllAtOnce/Reverse (maybe custom as well) 105 ### Deletion configuration ### 106 template: 107 metadata: 108 name: 'pricelist-{{srv}}' 109 labels: 110 pricelist-component: '{{srv}}' 111 spec: 112 project: default 113 syncPolicy: 114 automated: 115 prune: true 116 selfHeal: true 117 retry: 118 limit: 5 119 backoff: 120 duration: 5s 121 maxDuration: 3m0s 122 factor: 2 123 source: 124 repoURL: https://github.com/christianh814/gitops-examples 125 targetRevision: main 126 path: '{{path}}' 127 destination: 128 server: https://kubernetes.default.svc 129 namespace: pricelist 130 ``` 131 132 #### Reverse deletionStrategy: 133 ```yaml 134 apiVersion: argoproj.io/v1alpha1 135 kind: ApplicationSet 136 metadata: 137 name: pricelist 138 namespace: argocd 139 spec: 140 generators: 141 - list: 142 elements: 143 - srv: config 144 path: applicationsets/rollingsync/apps/pricelist-config 145 - srv: db 146 path: applicationsets/rollingsync/apps/pricelist-db 147 - srv: frontend 148 path: applicationsets/rollingsync/apps/pricelist-frontend 149 strategy: 150 type: RollingSync 151 rollingSync: 152 steps: 153 - matchExpressions: 154 - key: pricelist-component # the "key" is based on the label (below as "pricelist-component: {{srv}}") 155 operator: In 156 values: 157 - config 158 - matchExpressions: 159 - key: pricelist-component 160 operator: In 161 values: 162 - db 163 - matchExpressions: 164 - key: pricelist-component 165 operator: In 166 values: 167 - frontend 168 ### Deletion configuration ### 169 deletionOrder: Reverse # available options to be AllAtOnce/Reverse (maybe custom as well) 170 ### Deletion configuration ### 171 template: 172 metadata: 173 name: 'pricelist-{{srv}}' 174 labels: 175 pricelist-component: '{{srv}}' 176 spec: 177 project: default 178 syncPolicy: 179 automated: 180 prune: true 181 selfHeal: true 182 retry: 183 limit: 5 184 backoff: 185 duration: 5s 186 maxDuration: 3m0s 187 factor: 2 188 source: 189 repoURL: https://github.com/christianh814/gitops-examples 190 targetRevision: main 191 path: '{{path}}' 192 destination: 193 server: https://kubernetes.default.svc 194 namespace: pricelist 195 ``` 196 #### If custom deletionStrategy: 197 ```yaml 198 apiVersion: argoproj.io/v1alpha1 199 kind: ApplicationSet 200 metadata: 201 name: pricelist 202 namespace: argocd 203 spec: 204 generators: 205 - list: 206 elements: 207 - srv: config 208 path: applicationsets/rollingsync/apps/pricelist-config 209 - srv: db 210 path: applicationsets/rollingsync/apps/pricelist-db 211 - srv: frontend 212 path: applicationsets/rollingsync/apps/pricelist-frontend 213 strategy: 214 type: RollingSync 215 rollingSync: 216 steps: 217 - matchExpressions: 218 - key: pricelist-component # the "key" is based on the label (below as "pricelist-component: {{srv}}") 219 operator: In 220 values: 221 - config 222 - matchExpressions: 223 - key: pricelist-component 224 operator: In 225 values: 226 - db 227 - matchExpressions: 228 - key: pricelist-component 229 operator: In 230 values: 231 - frontend 232 ### Deletion configuration ### 233 deletionOrder: Custom # available options to be default/reverse/custom 234 deletionSync: 235 steps: 236 - matchExpressions: 237 - key: pricelist-component # the "key" is based on the label (below as "pricelist-component: {{srv}}") 238 operator: In 239 values: 240 - config 241 - matchExpressions: 242 - key: pricelist-component 243 operator: In 244 values: 245 - frontend 246 - matchExpressions: 247 - key: pricelist-component 248 operator: In 249 values: 250 - db 251 ### Deletion configuration ### 252 template: 253 metadata: 254 name: 'pricelist-{{srv}}' 255 labels: 256 pricelist-component: '{{srv}}' 257 spec: 258 project: default 259 syncPolicy: 260 automated: 261 prune: true 262 selfHeal: true 263 retry: 264 limit: 5 265 backoff: 266 duration: 5s 267 maxDuration: 3m0s 268 factor: 2 269 source: 270 repoURL: https://github.com/christianh814/gitops-examples 271 targetRevision: main 272 path: '{{path}}' 273 destination: 274 server: https://kubernetes.default.svc 275 namespace: pricelist 276 ``` 277 278 ### Implementation Details/Notes/Constraints [optional] 279 280 There should be a check that correlates the deletionStrategy to ApplicationSet strategy. For example can only select reverse 281 if rollingSync lists out an order of application deployment, otherwise should error out. 282 283 It was decided to have this field within strategy (which is a field associated with progressiveSync) 284 285 To be introduced in ApplicationSetStrategy as follows: 286 ```yaml 287 type ApplicationSetStrategy struct { 288 Type string `json:"type,omitempty" protobuf:"bytes,1,opt,name=type"` 289 RollingSync *ApplicationSetRolloutStrategy `json:"rollingSync,omitempty" protobuf:"bytes,2,opt,name=rollingSync"` 290 // RollingUpdate *ApplicationSetRolloutStrategy `json:"rollingUpdate,omitempty" protobuf:"bytes,3,opt,name=rollingUpdate"` 291 // Add DeletionSync Strategy here 292 DeletionOrder string `json:"deletionOrder,omitempty" protobuf:"bytes,4,opt,name=deletionOrder"` // takes value AllAtOnce/Reverse 293 } 294 295 ``` 296 297 Looked at the following names for this field: 298 1. DeletionSyncType 299 2. DeletionSyncStrategy 300 301 But decided on having DeletionOrder for the following reasons: 302 1. simpler to understand - Order is straightforward and thus sets expectation to user 303 2. Since it's nested within `strategy`, suffix of strategy isn't needed. 304 3. Leaving room for when/if it scales to have custom deletion strategy. i.e 305 ```yaml 306 type ApplicationSetStrategy struct { 307 Type string `json:"type,omitempty" protobuf:"bytes,1,opt,name=type"` 308 RollingSync *ApplicationSetRolloutStrategy `json:"rollingSync,omitempty" protobuf:"bytes,2,opt,name=rollingSync"` 309 // Add DeletionSync Strategy here 310 DeletionOrder string `json:"deletionOrder,omitempty" protobuf:"bytes,3,opt,name=deletionOrder"` // takes value AllAtOnce/Reverse/Custom 311 DeletionSync *ApplicationSetRolloutStrategy `json:"deletionSync,omitempty" protobuf:"bytes,4,opt,name=deletionSync"` 312 } 313 ``` 314 315 ### Detailed examples 316 Already covered in Use cases 317 318 ### Security Considerations 319 320 Since no additional roles or privileges are needed to be able to delete deployed applications in a specific order, 321 so no impact on the security aspects of Argo CD workloads. 322 323 324 ### Risks and Mitigations 325 326 No immediate Risks to consider 327 328 329 ### Upgrade / Downgrade Strategy 330 Introducing new fields to the ApplicationSet CRD, however, no existing fields are being changed. 331 This means that a new ApplicationSet version is unnecessary, and upgrading to the new spec with added fields will be a clean operation. 332 333 Downgrading could risk users receiving K8s API errors if they continue to try to apply the deletionStrategy field to a downgraded version of the ApplicationSet resource. 334 Downgrading the controller while keeping the upgraded version of the CRD should cleanly downgrade/revert the behavior of the controller to the previous version without requiring users to adjust their existing ApplicationSet specs. 335 336 337 ## Drawbacks 338 Slight increase in Argo CD code base complexity 339 340 ## Alternatives 341 TBD