github.com/argoproj/argo-cd/v3@v3.2.1/docs/operator-manual/upgrading/2.14-3.0.md (about)

     1  # v2.14 to 3.0
     2  
     3  Argo CD 3.0 is meant to be a low-risk upgrade containing only minor breaking changes. For each change, the next
     4  section will describe how to quickly determine if you are impacted, how to remediate the breaking change, and (if
     5  applicable) restore Argo CD 2.x default behavior.
     6  
     7  Once 3.0 is released, no more 2.x minor versions will be released. We will continue to cut patch releases for the two
     8  most recent minor versions (so 2.14 until 3.2 is released and 2.13 until 3.1 is released).
     9  
    10  ## Images missing release notes on GitHub
    11  
    12  !!! important
    13      Images 3.0.7 - 3.0.10 are missing release notes on GitHub. There was an issue with GoReleaser and building the darwin
    14      CLI that prevented the release notes from being published. More information can be found
    15      on [PR #23507](https://github.com/argoproj/argo-cd/pull/23507)
    16  
    17  ## Breaking Changes
    18  
    19  ### Fine-Grained RBAC for application `update` and `delete` sub-resources
    20  
    21  The default behavior of fine-grained policies have changed so they no longer apply to sub-resources.
    22  Prior to v3, policies granting `update` or `delete` to an application also applied to any of its sub-resources.
    23  
    24  Starting with v3, the `update` or `delete` actions only apply to the application itself. New policies must be defined
    25  to allow the `update/*` or `delete/*` actions on an Application's managed resources.
    26  
    27  The v2 behavior can be preserved by setting the config value `server.rbac.disableApplicationFineGrainedRBACInheritance`
    28  to `false` in the Argo CD ConfigMap `argocd-cm`.
    29  
    30  Read the [RBAC documentation](../rbac.md#fine-grained-permissions-for-updatedelete-action) for more detailed
    31  information.
    32  
    33  ### Logs RBAC enforcement as a first-class RBAC citizen
    34  
    35  2.4 introduced `logs` as a new RBAC resource. In 2.3 and lower, users with `applications, get` access automatically got logs access. In 2.4, it became possible to enable logs RBAC enforcement with a flag in `argocd-cm` ConfigMap:
    36  
    37  ```yaml
    38  server.rbac.log.enforce.enable: 'true'
    39  ```
    40  
    41  Starting from 3.0, this flag is removed and the logs RBAC is enforced by default, meaning the `logs` tab on `pod` view will not be visible without granting explicit `logs, get` permissions to the users/groups/roles requiring it.
    42  
    43  #### Detection
    44  
    45  Users who have `server.rbac.log.enforce.enable: "true"` in their `argocd-cm` ConfigMap, are unaffected by this change.
    46  
    47  Users who have `policy.default: role:readonly` or `policy.default: role:admin` in their `argocd-rbac-cm` ConfigMap, are unaffected.
    48  
    49  Users who don't have a `policy.default` in their `argocd-rbac-cm` ConfigMap, and either have `server.rbac.log.enforce.enable` set to `false` or don't have this setting at all in their `argocd-cm` ConfigMap are affected and should perform the below remediation steps.
    50  
    51  After the upgrade, it is recommended to remove the setting `server.rbac.log.enforce.enable` from `argocd-cm` ConfigMap, if it was there before the upgrade.
    52  
    53  #### Remediation
    54  
    55  ##### Quick remediation (global change)
    56  
    57  For users with an existing default policy with a custom role, add this policy to `policy.csv` for your custom role: `p, role:<YOUR_DEFAULT_ROLE>, logs, get, */*, allow`.
    58  For users without a default policy, add this policy to `policy.csv`: `p, role:global-log-viewer, logs, get, */*, allow` and add the default policy for this role: `policy.default: role:global-log-viewer`
    59  
    60  ##### Recommended remediation (per-policy change)
    61  
    62  Explicitly add a `logs, get` policy to every role that has a policy for `applications, get` or for `applications, *`.
    63  This is the recommended way to maintain the principle of least privilege.
    64  Similar to the way access to Applications are currently managed, access to logs can be either granted on a Project scope level (Project resource) or on the `argocd-rbac-cm` ConfigMap level.
    65  See this [example](../upgrading/2.3-2.4.md#example-1) for more details.
    66  
    67  ### Default `resource.exclusions` configurations
    68  
    69  Argo CD manifest now contains a default configuration for `resource.exclusions` in the `argocd-cm` to exclude resources that
    70  are known to be created by controllers and not usually managed in Git. The exclusions contain high volume and high churn objects
    71  which we exclude for performance reasons, reducing connections and load to the K8s API servers of managed clusters.
    72  
    73  The excluded Kinds are:
    74  
    75  - **Kubernetes Resources**: `Endpoints`, `EndpointSlice`, `Lease`, `SelfSubjectReview`, `TokenReview`, `LocalSubjectAccessReview`, `SelfSubjectAccessReview`, `SelfSubjectRulesReview`, `SubjectAccessReview`, `CertificateSigningRequest`, `PolicyReport` and `ClusterPolicyReport`.
    76  - **Cert Manager**: `CertificateRequest`.
    77  - **Kyverno**: `EphemeralReport`, `ClusterEphemeralReport`, `AdmissionReport`, `ClusterAdmissionReport`, `BackgroundScanReport`, `ClusterBackgroundScanReport` and `UpdateRequest`.
    78  - **Cilium**: `CiliumIdentity`, `CiliumEndpoint` and `CiliumEndpointSlice`.
    79  
    80  The default `resource.exclusions` can be overridden or removed in the configMap to preserve the v2 behavior.
    81  
    82  Read the [Declarative Setup](../declarative-setup.md) for more detailed information to configure `resource.exclusions`.
    83  
    84  ### Removal of `argocd_app_sync_status`, `argocd_app_health_status` and `argocd_app_created_time` Metrics
    85  
    86  The `argocd_app_sync_status`, `argocd_app_health_status` and `argocd_app_created_time`, deprecated and disabled by
    87  default since 1.5.0, have been removed. The information previously provided by these metrics is now available as labels
    88  on the `argocd_app_info` metric.
    89  
    90  #### Detection
    91  
    92  Starting with 1.5.0, these metrics are only available if `ARGOCD_LEGACY_CONTROLLER_METRICS` is explicitly set to `true`.
    93  If it is not set to true, you can safely upgrade with no changes.
    94  
    95  #### Migration
    96  
    97  If you are using these metrics, you will need to update your monitoring dashboards and alerts to use the new metric and
    98  labels before upgrading.
    99  
   100  ### Changes to RBAC with Dex SSO Authentication
   101  
   102  When using Dex, the `sub` claim returned in the authentication was used as the subject for RBAC. That value depends on
   103  the Dex internal implementation and should not be considered an immutable value that represents the subject.
   104  
   105  The new behavior will request the
   106  `federated:id` [scope](https://dexidp.io/docs/configuration/custom-scopes-claims-clients/) from Dex, and the new value
   107  used as the RBAC subject will be based
   108  on the `federated_claims.user_id` claim instead of the `sub` claim.
   109  
   110  If you were using the Dex sub claim in RBAC policies, you will need to update them to maintain the same access.
   111  
   112  You can know the correct `user_id` to use by decoding the current `sub` claims defined in your policies. You can also
   113  configure which
   114  value is used as `user_id` for some [connectors](https://dexidp.io/docs/connectors/).
   115  
   116  ```sh
   117  $> echo "ChdleGFtcGxlQGFyZ29wcm9qLmlvEgJkZXhfY29ubl9pZA" | base64 -d
   118  
   119  example@argoproj.iodex_conn_i%
   120  ```
   121  
   122  ```yaml
   123  # Policies based on the Dex sub claim (wrong)
   124  - g, ChdleGFtcGxlQGFyZ29wcm9qLmlvEgJkZXhfY29ubl9pZA, role:example
   125  - p, ChdleGFtcGxlQGFyZ29wcm9qLmlvEgJkZXhfY29ubl9pZA, applications, *, *, allow
   126  
   127  # Policies now based on federated_claims.user_id claim (correct)
   128  - g, example@argoproj.io, role:example
   129  - p, example@argoproj.io, applications, *, *, allow
   130  ```
   131  
   132  If authenticating with the CLI, make sure to use the new version as well to obtain an authentication token with the
   133  appropriate claims.
   134  
   135  ### Removed support for legacy repo config in argocd-cm
   136  
   137  Before repositories were managed as Secrets, they were configured in the argocd-cm ConfigMap. The argocd-cm option has
   138  been deprecated for some time and is no longer available in Argo CD 3.0.
   139  
   140  #### Detection
   141  
   142  To check whether you have any repositories configured in argocd-cm, run the following command:
   143  
   144  ```shell
   145  kubectl get cm argocd-cm -n argocd -o=jsonpath="[{.data.repositories}, {.data['repository\.credentials']}, {.data['helm\.repositories']}]"
   146  ```
   147  
   148  If you have no repositories configured in argocd-cm, the output will be `[, , ]`, and you are not impacted by this
   149  change.
   150  
   151  #### Migration
   152  
   153  To convert your repositories to Secrets, follow the documentation for
   154  [declarative management of repositories](../declarative-setup.md#repositories).
   155  
   156  ### Ignoring ApplicationSet `applyNestedSelectors` field
   157  
   158  Setting the `spec.applyNestedSelectors` field in an ApplicationSet resolves counter-intuitive behavior where filters in
   159  nested selectors were not applied. Starting in Argo CD 3.0, the field is ignored, and behavior is always the same as if
   160  `applyNestedSelectors` was set to `true`. In other words, nested selectors are always applied.
   161  
   162  #### Detection
   163  
   164  To detect if you are impacted, search your ApplicationSet controller logs for this string: `ignoring nested selector`.
   165  If there are no logs with this string, you are not impacted.
   166  
   167  Another way to detect if you are impacted is to run the following command:
   168  
   169  ```shell
   170  kubectl get appsets -o=json | jq -r '.items[] | select(
   171      .spec.applyNestedSelectors != true and
   172      .spec.generators[][].generators[][].generators[].selector != null
   173    ) | .metadata.name'
   174  ```
   175  
   176  The command will print the name of any ApplicationSet that has `applyNestedSelectors` unset or set to `false` and has
   177  one or more nested selectors.
   178  
   179  #### Remediation
   180  
   181  Since `applyNestedSelectors` is false by default, you can safely remove the nested selectors on ApplicationSets where
   182  `applyNestedSelectors` has not been explicitly set to `true`. After the selectors are removed, you can safely upgrade.
   183  
   184  For example, you should remove the selector in this ApplicationSet before upgrading to Argo CD 3.0.
   185  
   186  ```diff
   187  apiVersion: argoproj.io/v1alpha1
   188  kind: ApplicationSet
   189  metadata:
   190    name: guestbook
   191  spec:
   192    goTemplate: true
   193    goTemplateOptions: ["missingkey=error"]
   194    generators:
   195    - matrix:
   196        mergeKeys: ['test-key']
   197        generators:
   198        - list:
   199            elements:
   200            - test-key: 'test-value'
   201              cluster: staging
   202            - test-key: 'test-value'
   203              cluster: production
   204        - merge:
   205            generators:
   206            - list:
   207                elements:
   208                - another-key: 'another-value'
   209            - cluster: {}
   210  -           selector:
   211  -             matchLabels:
   212  -               app: guestbook
   213  
   214    template:
   215      metadata:
   216        name: '{{.cluster}}-guestbook'
   217      spec:
   218        project: my-project
   219        source:
   220          repoURL: https://github.com/infra-team/cluster-deployments.git
   221          targetRevision: HEAD
   222          path: guestbook/{{.cluster}}
   223        destination:
   224          server: '{{.url}}'
   225          namespace: guestbook
   226  ```
   227  
   228  ### Upgraded Helm version with breaking changes
   229  
   230  Helm was upgraded to 3.17.1.
   231  This may require changing your `values.yaml` files for subcharts, if the `values.yaml` contain a section with a `null` object.
   232  See related issue in [Helm GitHub repository](https://github.com/helm/helm/issues/12469)
   233  See Helm 3.17.1 [release notes](https://github.com/helm/helm/releases/tag/v3.17.1)
   234  Example of such a [problem and resolution](https://github.com/argoproj/argo-cd/pull/22035/files)
   235  Explanation:
   236  
   237  - Prior to Helm 3.17.1, `null` object in `values.yaml` resulted in a warning: `cannot overwrite table with non table` upon performing `helm template`, and the resulting K8s object was not overridden with the invalid `null` value.
   238  - In Helm 3.17.1, this behavior changed and `null` object in `values.yaml` still results in this warning upon performing `helm template`, but the resulting K8s object will be overridden with the invalid `null` value.
   239  - To resolve the issue, identify `values.yaml` with `null` object values, and remove those `null` values.
   240  
   241  ### Use Annotation-Based Tracking by Default
   242  
   243  The default behavior for [tracking resources](../../user-guide/resource_tracking.md) has changed to use annotation-based
   244  tracking instead of label-based tracking. Annotation-based tracking is more reliable and less prone to errors caused by
   245  external code copying tracking labels from one resource to another.
   246  
   247  #### Detection
   248  
   249  To detect if you are impacted, check the `argocd-cm` ConfigMap for the `application.resourceTrackingMethod` field. If it is
   250  unset or is set to `label`, you are using label-based tracking. If it is set to `annotation`, you are already using
   251  annotation-based tracking and are not impacted by this change.
   252  
   253  ```sh
   254  kubectl get cm argocd-cm -n argocd -o jsonpath='{.data.application\.resourceTrackingMethod}'
   255  ```
   256  If you are using label-based tracking, it is also important to detect whether you have Applications that use `ApplyOutOfSyncOnly=true` syncOptions, as such Applications are likely to have orphan resources after switching to `annotation` tracking method and need to be synced explicitly right after the upgrade.
   257  
   258  To detect whether you have such Applications, run:
   259  ```sh
   260  kubectl get applications.argoproj.io -A -o json | jq -r '.items[] | select(.spec.syncPolicy.syncOptions[]? == "ApplyOutOfSyncOnly=true") | .metadata.name'
   261  ```
   262  
   263  #### Remediation
   264  
   265  ##### Users with ApplyOutOfSyncOnly=true syncOptions and label-based tracking
   266  
   267  For users with label-based tracking and Applications that have `ApplyOutOfSyncOnly=true` syncOptions, an explicit sync has to be run for those Applications after you upgrade.
   268  Here is an example command, that syncs such an Application, it can be run after you [obtain a token](../../developer-guide/api-docs.md#authorization) to Argo CD API:
   269  ```sh
   270  curl -X POST -H "Authorization: Bearer $ARGOCD_TOKEN" -H "Content-Type: application/json" -d '{
   271      "name": "$YOUR_APP_NAME"
   272    }' "http://$YOUR_ARGOCD_URL/api/v1/applications/$YOUR_APP_NAME/sync"
   273  ```
   274  
   275  It is also possible to sync such an Applicaton using the UI, with `ApplyOutOfSyncOnly` option unchecked. However, currently, performing a sync without `ApplyOutOfSyncOnly` option is not possible using the CLI.
   276  
   277  ##### Other users
   278  
   279  For most users, it is safe to upgrade to Argo CD 3.0 and use annotation-based tracking. Labels will be replaced with
   280  annotations on the next sync. Applications will not be marked as out-of-sync if labels are not present on the
   281  resources.
   282  
   283  !!! warning "Potential for orphaned resources"
   284  
   285      There is a known edge case when switching from label-based tracking to annotation-based tracking that may cause
   286      resources to be orphaned. If the first sync operation after switching to annotation-based tracking includes a
   287      resource being deleted, Argo CD will fail to recognize that the resource is managed by the Application and will not
   288      delete it. To avoid this edge case, it is recommended to perform a sync operation on your Applications, even if
   289      they are not out of sync, so that orphan resource detection will work as expected on the next sync.
   290  
   291      After upgrading to version 3.0, the Argo CD tracking annotation will only appear on an Application’s resources when
   292      either a new Git commit is made or the Application is explicitly synced.
   293  
   294  ##### Users who rely on label-based for resources that are not managed by Argo CD
   295  Some users rely on label-based tracking to track resources that are not managed by Argo CD. They may set annotations
   296  to have Argo CD ignore the resource as extraneous or to disable pruning. If you are using label-based tracking to track
   297  resources that are not managed by Argo CD, you will need to construct tracking annotations instead of tracking labels
   298  and apply them to the relevant resources. The format of the tracking annotation is:
   299  
   300  ```yaml
   301  argocd.argoproj.io/tracking-id: <app name>:<resource group>/<resource kind>:<resource namespace>/<resource name>
   302  ```
   303  
   304  For cluster-scoped resources, the namespace is set to the value in the Application's `spec.destination.namespace` field.
   305  
   306  !!! warning
   307  
   308      Manually constructing and applying tracking labels and annotations is not an officially supported feature, and Argo
   309      CD's behavior may change in the future. It is recommended to manage resources with Argo CD via GitOps.
   310  
   311  #### Opting Out
   312  
   313  If you are not ready to use annotation-based tracking, you can opt out of this change by setting the
   314  `application.resourceTrackingMethod` field in the `argocd-cm` ConfigMap to `label`. There are no current plans to remove
   315  label-based tracking.
   316  
   317  ## Other changes
   318  
   319  ### Using `cluster.inClusterEnabled: "false"`
   320  
   321  When `cluster.inClusterEnabled: "false"` is explicitly configured, Applications currently configured to
   322  sync on the in-cluster cluster will now be in an Unknown state, without the possibility to sync resources.
   323  
   324  It will not be possible to create new Applications using the in-cluster cluster. When deleting existing
   325  Application, it will not delete the previously managed resources.
   326  
   327  It is recommended to perform any cleanup or migration to existing in-cluster Application before upgrading
   328  when in-cluster is disabled. To perform cleanup post-migration, the in-cluster will need to be enabled temporarily.
   329  
   330  ### Ignoring all status updates and high churn mutations
   331  
   332  Argo CD manifest now contains a default configuration for `resource.customizations.ignoreResourceUpdates` in the `argocd-cm`
   333  to exclude common resources that are often mutated in Kubernetes. These mutations are known to cause an unnecessary
   334  load on Argo CD. When a watched resource is modified, Argo CD will always ignore the `.status` changes.
   335  
   336  The default `resource.customizations.ignoreResourceUpdates` configurations can be overridden or removed in the configMap to preserve the v2 behavior.
   337  
   338  ### Health status in the Application CR
   339  
   340  The health status of each object used to be persisted under `/status` in the Application CR by default.
   341  Any health churn in the resources deployed by the Application put load on the application controller.
   342  Now, the health status is stored externally.
   343  
   344  You can revert this behavior by setting the `controller.resource.health.persist` to `true` in the Argo CD
   345  `argocd-cmd-params-cm.yaml` Config Map.
   346  
   347  Example of a status field in the Application CR persisting health:
   348  
   349  ```yaml
   350  status:
   351    health:
   352      status: Healthy
   353      lastTransitionTime: '2025-01-01T00:00:00Z'
   354    resources:
   355      - group: apps
   356        health:
   357          status: Healthy
   358        kind: Deployment
   359        name: my-app
   360        namespace: foo
   361        status: OutOfSync
   362        version: v1
   363    sync:
   364      status: OutOfSync
   365  ```
   366  
   367  Example of a status field in the Application CR _not_ persisting health:
   368  
   369  ```yaml
   370  status:
   371    health:
   372      status: Healthy
   373      lastTransitionTime: '2025-01-01T00:00:00Z'
   374    resourceHealthSource: appTree
   375    resources:
   376      - group: apps
   377        kind: Deployment
   378        name: my-app
   379        namespace: foo
   380        status: OutOfSync
   381        version: v1
   382    sync:
   383      status: OutOfSync
   384  ```
   385  
   386  #### Detection
   387  
   388  1. Check the `argocd-cmd-params-cm.yaml` ConfigMap for `controller.resource.health.persist`.
   389  
   390     If the value is empty or true, the health status is persisted in the Application CR.
   391  
   392  ```sh
   393  kubectl get cm argocd-cmd-params-cm -n argocd -o jsonpath='{.data.controller\.resource\.health\.persist}'
   394  ```
   395  
   396  2. Check any Application CR for the `resourceHealthSource` field.
   397     If you see a blank value, the health status is persisted in the Application CR.
   398  
   399  ```sh
   400  kubectl get applications.argoproj.io <my app> -n argocd -o jsonpath='{.status.resourceHealthSource}'
   401  ```
   402  
   403  #### Migration
   404  
   405  Any tools or CLI commands parsing the `.status.resources[].health` need to be updated to use the argocd cli/API to get the health status.
   406  
   407  !!! note
   408      The application list API (argocd app list) no longer returns the individual health status of resources.
   409  
   410  ```sh
   411  argocd app get <my app> -o json
   412  ```
   413  
   414  ### Empty Environment Variables in Plugins
   415  
   416  In Argo CD 3.0, empty environment variables are now passed to config management plugins.
   417  
   418  ```yaml
   419  apiVersion: argoproj.io/v1alpha1
   420  kind: Application
   421  spec:
   422    source:
   423      plugin:
   424        name: example-plugin
   425        env:
   426          - name: VERSION
   427            value: '1.2.3'
   428          - name: DATA # Even though this is empty, it will be passed to the plugin as ARGOCD_ENV_DATA="".
   429            value: ''
   430  ```
   431  
   432  ### Ignoring resource updates configured in `ignoreDifferences` by default
   433  
   434  By default, the existing system-level `ignoreDifferences` customizations will be added to ignore resource updates as well.
   435  
   436  Logically, if differences to a field are configured to be ignored, there is no reason to generate the diff for the application
   437  when that field changes.
   438  
   439  To disable this behavior and preserve the v2 default, the `ignoreDifferencesOnResourceUpdates` can be set to false:
   440  
   441  ```yaml
   442  apiVersion: v1
   443  kind: ConfigMap
   444  metadata:
   445    name: argocd-cm
   446  data:
   447    resource.compareoptions: |
   448      ignoreDifferencesOnResourceUpdates: false
   449  ```
   450  
   451  More details for ignored resource updates in the [Reconcile Optimization](../reconcile.md) documentation.
   452  
   453  ### Ignoring status field from differences by default
   454  
   455  By default, the compare options to ignore the status field has been changed from `crd` to `all` resources.
   456  
   457  This means that differences won't be detected anymore for fields that are part of the status.
   458  
   459  If you rely on the status field being part of your desired state, the `ignoreResourceStatusField` setting can be used to preserve the v2 default.
   460  
   461  ```yaml
   462  apiVersion: v1
   463  kind: ConfigMap
   464  metadata:
   465    name: argocd-cm
   466  data:
   467    resource.compareoptions: |
   468      ignoreResourceStatusField: crd
   469  ```
   470  
   471  ### Removing default ignores of `preserveUnknownFields` for CRD
   472  
   473  The `spec.preserveUnknownFields` has been deprecated in favor of `x-kubernetes-preserve-unknown-fields: true` in the CRD v1.
   474  
   475  This means that CRD deployed with Argo CD containing `spec.preserveUnknownFields: false` will be out of sync. To address this problem,
   476  the `preserveUnknownFields` field can be removed from the CRD spec.
   477  
   478  Until this is completed, if you want your Application not to be out of sync, you can add the following configuration to the Application manifest.
   479  
   480  ```yaml
   481  spec:
   482    ignoreDifferences:
   483      - group: apiextensions.k8s.io
   484        kind: CustomResourceDefinition
   485        jsonPointers:
   486          - /spec/preserveUnknownFields
   487  ```
   488  
   489  You can also configure it globally in the `argocd-cm` ConfigMap.
   490  
   491  ```yaml
   492  resource.customizations.ignoreDifferences.apiextensions.k8s.io_CustomResourceDefinition: |
   493      jsonPointers:
   494      - /spec/preserveUnknownFields
   495  ```
   496  
   497  More details for ignored resource updates in the [Diffing customization](../../user-guide/diffing.md) documentation.
   498  
   499  ### Sanitized project API response
   500  
   501  Due to security reasons ([GHSA-786q-9hcg-v9ff](https://github.com/argoproj/argo-cd/security/advisories/GHSA-786q-9hcg-v9ff)),
   502  the project API response was sanitized to remove sensitive information. This includes
   503  credentials of project-scoped repositories and clusters.