Skip to content

Merge Generator

The Merge generator combines parameters produced by the base (first) generator with matching parameter sets produced by subsequent generators. A matching parameter set has the same values for the configured merge keys. Non-matching parameter sets are discarded. Override precedence is bottom-to-top: the values from a matching parameter set produced by generator 3 will take precedence over the values from the corresponding parameter set produced by generator 2.

Using a Merge generator is appropriate when a subset of parameter sets require overriding.

Example: Base Cluster generator + override Cluster generator + List generator

As an example, imagine that we have two clusters:

  • A staging cluster (at https://1.2.3.4)
  • A production cluster (at https://2.4.6.8)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-git
spec:
  generators:
    # merge 'parent' generator
    - merge:
        mergeKeys:
          - server
        generators:
          - clusters:
              values:
                kafka: 'true'
                redis: 'false'
          # For clusters with a specific label, enable Kafka.
          - clusters:
              selector:
                matchLabels:
                  use-kafka: 'false'
              values:
                kafka: 'false'
          # For a specific cluster, enable Redis.
          - list:
              elements: 
                - server: https://2.4.6.8
                  values.redis: 'true'
  template:
    metadata:
      name: '{{name}}'
    spec:
      project: '{{metadata.labels.environment}}'
      source:
        repoURL: https://github.com/argoproj-labs/applicationset.git
        targetRevision: HEAD
        path: app
        helm:
          parameters:
            - name: kafka
              value: '{{values.kafka}}'
            - name: redis
              value: '{{values.redis}}'
      destination:
        server: '{{server}}'
        namespace: default

The base Cluster generator scans the set of clusters defined in Argo CD, finds the staging and production cluster secrets, and produces two corresponding sets of parameters:

- name: staging
  server: https://1.2.3.4
  values.kafka: 'true'
  values.redis: 'false'

- name: production
  server: https://2.4.6.8
  values.kafka: 'true'
  values.redis: 'false'

The override Cluster generator scans the set of clusters defined in Argo CD, finds the staging cluster secret (which has the required label), and produces the following parameters:

- name: staging
  server: https://1.2.3.4
  values.kafka: 'false'

When merged with the base generator's parameters, the values.kafka value for the staging cluster is set to 'false'.

- name: staging
  server: https://1.2.3.4
  values.kafka: 'false'
  values.redis: 'false'

- name: production
  server: https://2.4.6.8
  values.kafka: 'true'
  values.redis: 'false'

Finally, the List cluster generates a single set of parameters:

- server: https://2.4.6.8
  values.redis: 'true'

When merged with the updated base parameters, the values.redis value for the production cluster is set to 'true'. This is the merge generator's final output:

- name: staging
  server: https://1.2.3.4
  values.kafka: 'false'
  values.redis: 'false'

- name: production
  server: https://2.4.6.8
  values.kafka: 'true'
  values.redis: 'true'

Restrictions

  1. You should specify only a single generator per array entry. This is not valid:
    - merge:
        generators:
         - list: # (...)
           git: # (...)
    
    • While this will be accepted by Kubernetes API validation, the controller will report an error on generation. Each generator should be specified in a separate array element, as in the examples above.
  2. The Merge generator does not support template overrides specified on child generators. This template will not be processed:
    - merge:
        generators:
          - list:
              elements:
                - # (...)
              template: { } # Not processed
    
  3. Combination-type generators (Matrix or Merge) can only be nested once. For example, this will not work:
    - merge:
        generators:
          - merge:
              generators:
                - merge:  # This third level is invalid.
                    generators:
                      - list:
                          elements:
                            - # (...)