github.com/argoproj/argo-cd/v3@v3.2.1/docs/operator-manual/applicationset/Generators-Cluster.md (about) 1 # Cluster Generator 2 3 In Argo CD, managed clusters [are stored within Secrets](../../declarative-setup/#clusters) in the Argo CD namespace. The ApplicationSet controller uses those same Secrets to generate parameters to identify and target available clusters. 4 5 For each cluster registered with Argo CD, the Cluster generator produces parameters based on the list of items found within the cluster secret. 6 7 It automatically provides the following parameter values to the Application template for each cluster: 8 9 - `name` 10 - `nameNormalized` *('name' but normalized to contain only lowercase alphanumeric characters, '-' or '.')* 11 - `server` 12 - `project` *(the Secret's 'project' field, if present; otherwise, it defaults to '')* 13 - `metadata.labels.<key>` *(for each label in the Secret)* 14 - `metadata.annotations.<key>` *(for each annotation in the Secret)* 15 16 !!! note 17 Use the `nameNormalized` parameter if your cluster name contains characters (such as underscores) that are not valid for Kubernetes resource names. This prevents rendering invalid Kubernetes resources with names like `my_cluster-app1`, and instead would convert them to `my-cluster-app1`. 18 19 20 Within [Argo CD cluster Secrets](../../declarative-setup/#clusters) are data fields describing the cluster: 21 ```yaml 22 kind: Secret 23 data: 24 # Within Kubernetes these fields are actually encoded in Base64; they are decoded here for convenience. 25 # (They are likewise decoded when passed as parameters by the Cluster generator) 26 config: "{'tlsClientConfig':{'insecure':false}}" 27 name: "in-cluster2" 28 server: "https://kubernetes.default.svc" 29 metadata: 30 labels: 31 argocd.argoproj.io/secret-type: cluster 32 # (...) 33 ``` 34 35 The Cluster generator will automatically identify clusters defined with Argo CD, and extract the cluster data as parameters: 36 ```yaml 37 apiVersion: argoproj.io/v1alpha1 38 kind: ApplicationSet 39 metadata: 40 name: guestbook 41 namespace: argocd 42 spec: 43 goTemplate: true 44 goTemplateOptions: ["missingkey=error"] 45 generators: 46 - clusters: {} # Automatically use all clusters defined within Argo CD 47 template: 48 metadata: 49 name: '{{.name}}-guestbook' # 'name' field of the Secret 50 spec: 51 project: "my-project" 52 source: 53 repoURL: https://github.com/argoproj/argocd-example-apps/ 54 targetRevision: HEAD 55 path: guestbook 56 destination: 57 server: '{{.server}}' # 'server' field of the secret 58 namespace: guestbook 59 ``` 60 (*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/cluster).*) 61 62 In this example, the cluster secret's `name` and `server` fields are used to populate the `Application` resource `name` and `server` (which are then used to target that same cluster). 63 64 ### Label selector 65 66 A label selector may be used to narrow the scope of targeted clusters to only those matching a specific label: 67 ```yaml 68 apiVersion: argoproj.io/v1alpha1 69 kind: ApplicationSet 70 metadata: 71 name: guestbook 72 namespace: argocd 73 spec: 74 goTemplate: true 75 goTemplateOptions: ["missingkey=error"] 76 generators: 77 - clusters: 78 selector: 79 matchLabels: 80 staging: "true" 81 # The cluster generator also supports matchExpressions. 82 #matchExpressions: 83 # - key: staging 84 # operator: In 85 # values: 86 # - "true" 87 template: 88 # (...) 89 ``` 90 91 This would match an Argo CD cluster secret containing: 92 ```yaml 93 apiVersion: v1 94 kind: Secret 95 data: 96 # (... fields as above ...) 97 metadata: 98 labels: 99 argocd.argoproj.io/secret-type: cluster 100 staging: "true" 101 # (...) 102 ``` 103 104 The cluster selector also supports set-based requirements, as used by [several core Kubernetes resources](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements). 105 106 ### Deploying to the local cluster 107 108 In Argo CD, the 'local cluster' is the cluster upon which Argo CD (and the ApplicationSet controller) is installed. This is to distinguish it from 'remote clusters', which are those that are added to Argo CD [declaratively](../../declarative-setup/#clusters) or via the [Argo CD CLI](../../getting_started.md/#5-register-a-cluster-to-deploy-apps-to-optional). 109 110 The cluster generator will automatically target both local and non-local clusters, for every cluster that matches the cluster selector. 111 112 If you wish to target only remote clusters with your Applications (e.g. you want to exclude the local cluster), then use a cluster selector with labels, for example: 113 ```yaml 114 spec: 115 goTemplate: true 116 goTemplateOptions: ["missingkey=error"] 117 generators: 118 - clusters: 119 selector: 120 matchLabels: 121 argocd.argoproj.io/secret-type: cluster 122 # The cluster generator also supports matchExpressions. 123 #matchExpressions: 124 # - key: staging 125 # operator: In 126 # values: 127 # - "true" 128 ``` 129 130 This selector will not match the default local cluster, since the default local cluster does not have a Secret (and thus does not have the `argocd.argoproj.io/secret-type` label on that secret). Any cluster selector that selects on that label will automatically exclude the default local cluster. 131 132 However, if you do wish to target both local and non-local clusters, while also using label matching, you can create a secret for the local cluster within the Argo CD web UI: 133 134 1. Within the Argo CD web UI, select *Settings*, then *Clusters*. 135 2. Select your local cluster, usually named `in-cluster`. 136 3. Click the *Edit* button, and change the *NAME* of the cluster to another value, for example `in-cluster-local`. Any other value here is fine. 137 4. Leave all other fields unchanged. 138 5. Click *Save*. 139 140 These steps might seem counterintuitive, but the act of changing one of the default values for the local cluster causes the Argo CD Web UI to create a new secret for this cluster. In the Argo CD namespace, you should now see a Secret resource named `cluster-(cluster suffix)` with label `argocd.argoproj.io/secret-type": "cluster"`. You may also create a local [cluster secret declaratively](../../declarative-setup/#clusters), or with the CLI using `argocd cluster add "(context name)" --in-cluster`, rather than through the Web UI. 141 142 ### Fetch clusters based on their K8s version 143 144 There is also the possibility to fetch clusters based upon their Kubernetes version. To do this, the label `argocd.argoproj.io/auto-label-cluster-info` needs to be set to `true` on the cluster secret. 145 Once that has been set, the controller will dynamically label the cluster secret with the Kubernetes version it is running on. To retrieve that value, you need to use the 146 `argocd.argoproj.io/kubernetes-version`, as the example below demonstrates: 147 148 ```yaml 149 spec: 150 goTemplate: true 151 generators: 152 - clusters: 153 selector: 154 matchLabels: 155 argocd.argoproj.io/kubernetes-version: 1.28 156 # matchExpressions are also supported. 157 #matchExpressions: 158 # - key: argocd.argoproj.io/kubernetes-version 159 # operator: In 160 # values: 161 # - "1.27" 162 # - "1.28" 163 ``` 164 165 ### Pass additional key-value pairs via `values` field 166 167 You may pass additional, arbitrary string key-value pairs via the `values` field of the cluster generator. Values added via the `values` field are added as `values.(field)` 168 169 In this example, a `revision` parameter value is passed, based on matching labels on the cluster secret: 170 ```yaml 171 spec: 172 goTemplate: true 173 goTemplateOptions: ["missingkey=error"] 174 generators: 175 - clusters: 176 selector: 177 matchLabels: 178 type: 'staging' 179 # A key-value map for arbitrary parameters 180 values: 181 revision: HEAD # staging clusters use HEAD branch 182 - clusters: 183 selector: 184 matchLabels: 185 type: 'production' 186 values: 187 # production uses a different revision value, for 'stable' branch 188 revision: stable 189 template: 190 metadata: 191 name: '{{.name}}-guestbook' 192 spec: 193 project: "my-project" 194 source: 195 repoURL: https://github.com/argoproj/argocd-example-apps/ 196 # The cluster values field for each generator will be substituted here: 197 targetRevision: '{{.values.revision}}' 198 path: guestbook 199 destination: 200 server: '{{.server}}' 201 namespace: guestbook 202 ``` 203 204 In this example the `revision` value from the `generators.clusters` fields is passed into the template as `values.revision`, containing either `HEAD` or `stable` (based on which generator generated the set of parameters). 205 206 !!! note 207 The `values.` prefix is always prepended to values provided via `generators.clusters.values` field. Ensure you include this prefix in the parameter name within the `template` when using it. 208 209 In `values` we can also interpolate the following parameter values (i.e. the same values as presented in the beginning of this page) 210 211 - `name` 212 - `nameNormalized` *('name' but normalized to contain only lowercase alphanumeric characters, '-' or '.')* 213 - `server` 214 - `metadata.labels.<key>` *(for each label in the Secret)* 215 - `metadata.annotations.<key>` *(for each annotation in the Secret)* 216 217 Extending the example above, we could do something like this: 218 219 ```yaml 220 spec: 221 goTemplate: true 222 goTemplateOptions: ["missingkey=error"] 223 generators: 224 - clusters: 225 selector: 226 matchLabels: 227 type: 'staging' 228 # A key-value map for arbitrary parameters 229 values: 230 # If `my-custom-annotation` is in your cluster secret, `revision` will be substituted with it. 231 revision: '{{index .metadata.annotations "my-custom-annotation"}}' 232 clusterName: '{{.name}}' 233 - clusters: 234 selector: 235 matchLabels: 236 type: 'production' 237 values: 238 # production uses a different revision value, for 'stable' branch 239 revision: stable 240 clusterName: '{{.name}}' 241 template: 242 metadata: 243 name: '{{.name}}-guestbook' 244 spec: 245 project: "my-project" 246 source: 247 repoURL: https://github.com/argoproj/argocd-example-apps/ 248 # The cluster values field for each generator will be substituted here: 249 targetRevision: '{{.values.revision}}' 250 path: guestbook 251 destination: 252 # In this case this is equivalent to just using {{name}} 253 server: '{{.values.clusterName}}' 254 namespace: guestbook 255 ``` 256 ### Gather cluster information as a flat list 257 258 You may sometimes need to gather your clusters information, without having to deploy one application per cluster found. 259 For that, you can use the option `flatList` in the cluster generator. 260 261 Here is an example of cluster generator using this option: 262 ```yaml 263 spec: 264 goTemplate: true 265 goTemplateOptions: ["missingkey=error"] 266 generators: 267 - clusters: 268 selector: 269 matchLabels: 270 type: 'staging' 271 flatList: true 272 template: 273 metadata: 274 name: 'flat-list-guestbook' 275 spec: 276 project: "my-project" 277 source: 278 repoURL: https://github.com/argoproj/argocd-example-apps/ 279 # The cluster values field for each generator will be substituted here: 280 targetRevision: 'HEAD' 281 path: helm-guestbook 282 helm: 283 values: | 284 clusters: 285 {{- range .clusters }} 286 - name: {{ .name }} 287 {{- end }} 288 destination: 289 # In this case this is equivalent to just using {{name}} 290 server: 'my-cluster' 291 namespace: guestbook 292 ``` 293 294 Given that you have two cluster secrets matching with names cluster1 and cluster2, this would generate the **single** following Application: 295 296 ```yaml 297 apiVersion: argoproj.io/v1alpha1 298 kind: Application 299 metadata: 300 name: flat-list-guestbook 301 namespace: guestbook 302 spec: 303 project: "my-project" 304 source: 305 repoURL: https://github.com/argoproj/argocd-example-apps/ 306 targetRevision: 'HEAD' 307 path: helm-guestbook 308 helm: 309 values: | 310 clusters: 311 - name: cluster1 312 - name: cluster2 313 ``` 314 315 In case you are using several cluster generators, each with the flatList option, one Application would be generated by cluster generator, as we can't simply merge values and templates that would potentially differ in each generator.