github.com/argoproj/argo-cd/v2@v2.10.5/docs/proposals/application-name-identifier.md (about) 1 --- 2 title: Change the way application resources are identified 3 authors: 4 - "@jannfis" 5 sponsors: 6 - TBD 7 reviewers: 8 - TBD 9 approvers: 10 - TBD 11 12 creation-date: 2021-06-07 13 last-updated: 2021-06-07 14 --- 15 16 # Change the way application resources are identified 17 18 This is a proposal to introduce the tracking method settings that allows using 19 an annotation as the application identifier instead of the application instance label. 20 This will allow application names longer than 63 characters and solve issues caused by 21 copying `app.kubernetes.io/instance` label. As an additional goal, we propose to introduce an 22 installation ID that will allow multiple Argo CD instances to manage resources 23 on the same cluster. 24 25 26 ## Summary 27 28 Argo CD identifies resources it manages by setting the _application instance 29 label_ to the name of the managing `Application` on all resources that are 30 managed (i.e. reconciled from Git). The default label used is the well-known 31 label `app.kubernetes.io/instance`. 32 33 This proposal suggests to introduce the `trackingMethod` setting that allows 34 controlling how applicaton resources are identified and allows switching to 35 using the annotation instead of `app.kubernetes.io/instance` label. 36 37 ## Motivation 38 39 The main motivation behind this change is to solve the following known issues: 40 41 * The Kubernetes label value cannot be longer than 63 characters. In large scale 42 installations, in order to build up an easy to understand and 43 well-formed naming schemes for applications managed by Argo CD, people often 44 hit the 63 character limit and need to define the naming scheme around this 45 unnecessary limit. 46 47 * Popular off-the-shelf Helm charts often add the `app.kubernetes.io/instance` label 48 to the generated resource manifests. This label confuses Argo CD and makes it think the 49 resource is managed by the application. 50 51 * Kubernetes operators often create additional resources without creating owner reference 52 and copy the `app.kubernetes.io/instance` label from the application resource. This is 53 also confusing Argo CD and makes it think the resource is managed by the application. 54 55 An additional motivation - while we're at touching at application instance 56 label - is to improve the way how multiple Argo CD instances could manage 57 applications on the same cluster, without requiring the user to actually 58 perform instance specific configuration. 59 60 ### Goals 61 62 * Allow application names of more than 63 characters 63 64 * Prevent confusion caused by copied/generated `app.kubernetes.io/instance` label 65 66 * Keep having a human-readable way to identify resources that belong to a 67 given Argo CD application 68 69 * As a stretch-goal, allow multiple Argo CD instances to manage resources on 70 the same cluster without the need for configuring application instance label 71 key (usually `app.kubernetes.io/instance`) 72 73 ### Non-Goals 74 75 * Change the default name of the application instance label 76 77 ## Proposal 78 79 We propose introducing a new setting `trackingMethod` that allows to control 80 how application resources are identified. The `trackingMethod` setting takes 81 one of the following values: 82 83 * `label` (default) - Argo CD keep using the `app.kubernetes.io/instance` label. 84 * `annotation+label` - Argo CD keep adding `app.kubernetes.io/instance` but only 85 for informational purposes: label is not used for tracking, value is truncated if 86 longer than 63 characters. The `app.kubernetes.io/instance` annotation is used 87 to track application resources. 88 * `annotation` - Argo CD uses the `app.kubernetes.io/instance` annotation to track 89 application resources. 90 91 The `app.kubernetes.io/instance` attribute values includes the application name, 92 resources identifier it is applied to, and optionally the Argo CD installation ID: 93 94 The application name allows to identify the application that manages the resource. The 95 resource identifier prevents confusion if an operation copies the 96 `app.kubernetes.io/instance` annotation to another resource. Finally optional 97 installation ID allows separate two Argo CD instances that manages resources in the same cluster. 98 99 The `trackingMethod` setting should be available at the system level and the application level to 100 allow the smooth transition from the old `app.kubernetes.io/instance` label to the new tracking method. 101 Using the app leverl settings users will be able to first switch applications one by one to the new tracking method 102 and prepare for the migration. Next system level setting can be changed to `annotation` or `annotation+label` 103 and not-migrated applications can be configured to use `labels` using application level setting. 104 105 106 ### Use cases 107 108 Add a list of detailed use cases this enhancement intends to take care of. 109 110 #### Use case 1: Allow for more than 63 characters in application name 111 112 As a user, I would like to be able to give my applications names with arbitrary 113 length, because I want to include identifiers like target regions and possibly 114 availability zones, the environment and possibly other identifiers (e.g. a team 115 name) in the application names. The current restriction of 63 characters is not 116 sufficient for my naming requirements. 117 118 #### Use case 2: Allow for retrieving all resources using Kubernetes 119 120 As an administrator, I want to enable my users to use more than 63 characters 121 in their application names, but I still want to be able to retrieve all of the 122 resources managed by that particular application using Kubernetes mechanisms, 123 e.g. a label selector as in the following example: 124 125 ``` 126 kubectl get deployments -l app.kubernetes.io/instance=<application> --all-namespaces 127 ``` 128 129 #### Use case 3: Multiple Argo CD instances managing apps on same cluster 130 131 I also want to be able to see which application and Argo CD instance is the 132 one in charge of a given resource. 133 134 ### Implementation Details/Notes/Constraints [optional] 135 136 #### Include resource identifies in the `app.kubernetes.io/instance` annotation 137 138 The `app.kubernetes.io/instance` annotation might be accidently added or copied 139 same as label. To prevent Argo CD confusion the annotation value should include 140 the identifier of the resource annotation was applied to. The resource identifier 141 includes the group, kind, namespace and name of the resource. It is proposed to use `;` 142 to separate identifier from the application name. 143 144 ```yaml 145 annotations: 146 app.kubernetes.io/instance: <application-name>;<group>/<kind>/<namespace>/<name> 147 ``` 148 149 Example: 150 151 ```yaml 152 apiVersion: apps/v1 153 kind: Deployment 154 metadata: 155 name: my-deployment 156 namespace: default 157 annotations: 158 app.kubernetes.io/instance: my-application;apps/Deployment/default/my-deployment 159 ``` 160 161 #### Allow multiple Argo CD instances manage applications on same cluster 162 163 As of today, to allow two or more Argo CD instances with a similar set of 164 permissions (e.g. cluster-wide read access to resources) manage applications 165 on the same cluster, users would have to configure the _application instance 166 label key_ in the Argo CD configuration to a unique value. Otherwise, if an 167 application with the same name exists in two different Argo CD installations, 168 both would claim ownership of the resources of that application. 169 170 We do see the need for preventing such scenarios out-of-the-box in Argo CD. 171 For this, we do suggest the introduction of an _installation ID_ in the 172 form of a standard _GUID_. 173 174 This GUID would be generated once by Argo CD upon startup, and is persisted in 175 the Argo CD configuration, e.g. by storing it as `installationID` in the 176 `argocd-cm` ConfigMap. The GUID of the installation would need to be encoded 177 in some way in the resources managed by that Argo CD instance. 178 179 We suggest using a dedicated annotation to store the GUID and modify Argo CD so that it matches _both_, the app 180 instance key and the GUID to determine whether a resource is managed by 181 this Argo CD instance. Given above mentioned GUID, this may look like the 182 following on a resource: 183 184 ```yaml 185 apiVersion: v1 186 Kind: Secret 187 metadata: 188 name: some-secret 189 namespace: some-namespace 190 annotations: 191 app.kubernetes.io/instance: my-application;/Secret/some-namespace/some-secret 192 argo-cd.argoproj.io/installation-id: 61199294-412c-4e78-a237-3ebba6784fcd 193 ``` 194 195 The user should be able to opt-out of this feature by setting the `installationID` to an empty string. 196 197 ### Security Considerations 198 199 We think this change will not have a direct impact on the security of Argo CD 200 or the applications it manages. 201 202 ### Risks and Mitigations 203 204 The proposal assumes that user can keep adding `app.kubernetes.io/instance` label 205 to be able to retrieve resources using `kubectl get -l app.kubernetes.io/instance=<application>` command. 206 However, Argo CD is going to truncate the value of the label if it is longer than 63 characters. There is 207 a small possibility that there are several applications with the same first 63 characters in the name. This 208 should be clearly stated in documentation. 209 210 ### Upgrade / Downgrade Strategy 211 212 Upgrading to a version that implements this proposal should be seamless, as 213 previously injected labels will not be removed and additional annotations will 214 be applied to the resource. E.g. consider following resource in Git, that will 215 be synced as part of an application named `some-application`. In Git, the 216 resource looks like follows: 217 218 ```yaml 219 apiVersion: v1 220 Kind: Secret 221 metadata: 222 name: some-secret 223 namespace: some-namespace 224 ``` 225 226 When synced with the current incarnation of Argo CD, Argo CD would inject the 227 application instance label and once the resource is applied in the cluster, it 228 would look like follows: 229 230 ```yaml 231 apiVersion: v1 232 Kind: Secret 233 metadata: 234 name: some-secret 235 namespace: some-namespace 236 labels: 237 app.kubernetes.io/instance: some-application 238 ``` 239 240 Once Argo CD is updated to a version implementing this proposal, the resource 241 would be rewritten to look like the following: 242 243 ```yaml 244 apiVersion: v1 245 Kind: Secret 246 metadata: 247 name: some-secret 248 namespace: some-namespace 249 labels: 250 app.kubernetes.io/instance: some-application 251 annotations: 252 app.kubernetes.io/instance: my-application;/Secret/some-namespace/some-secret 253 argo-cd.argoproj.io/installation-id: 61199294-412c-4e78-a237-3ebba6784fcd 254 ``` 255 256 On a rollback to a previous Argo CD version, this change would be reverted 257 and the resource would look like the first shown example above. 258 259 ## Drawbacks 260 261 We do see some drawbacks to this implementation: 262 263 * This change would trigger a re-sync of each and every managed resource, which 264 may result in unexpected heavy load on Argo CD and the cluster at upgrade 265 time. The workaround is an ability to opt-out of this as a default and enable it 266 on application basis. 267 268 ## Alternatives 269 270 * Enabling application names longer than 63 characters could also be done 271 by using the hashed value of the application name and additional metadata as a label. 272 The disadvantage of this approach is that hash value is not human friendly. In particular, 273 it is difficult to retrieve application manifests using `kubectl get -l app.kubernetes.io/instance=<application>`.