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.