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