argoproj / argo-cd

Declarative Continuous Deployment for Kubernetes
https://argo-cd.readthedocs.io
Apache License 2.0
18.01k stars 5.49k forks source link

elementsYaml is not working in nested matrix #16578

Open sangcom15 opened 11 months ago

sangcom15 commented 11 months ago

Checklist:

Describe the bug

I was trying to use 'elementsYaml' of list generator. i referred to https://argo-cd.readthedocs.io/en/release-2.9/operator-manual/applicationset/Generators-List/#dynamically-generated-elements and it worked. But when i use 'elementsYaml' of list generator in nested matrix, it is not working with the error message below. failed to get params for second generator in the matrix generator: child generator returned an error on parameter generation: failed to replace parameters in generator: failed to execute go template {{ .app.charts | toJson }}: template: :1:7: executing "" at <.app.charts>: map has no entry for key "app"

To Reproduce

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: s01-env
  namespace: argocd
  annotations:
    argocd.argoproj.io/sync-wave: "0"
  labels:
    appName: s01
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  syncPolicy: {}
  generators:
    - matrix:
        generators:
          - pullRequest:
              github:
                owner: myorg
                repo: dev-env
                api: https://github.mycompany.com/api/v3/
                tokenRef:
                  secretName: argocd-repo-creds-github
                  key: password
                labels:
                - deploy
              requeueAfterSeconds: 30
          - matrix:
              generators:
                - git:
                    repoURL: https://github.mycompany.com/myorg/dev-env.git
                    revision: '{{.head_sha}}'
                    files:
                      - path: configs/config.yaml
                    requeueAfterSeconds: 30
                - list: # charts
                    elements: []
                    elementsYaml: "{{ .app.charts | toJson }}"
  template:
    metadata:
      name: 'app-{{.app.env.project}}-{{.branch_slug}}-{{.number}}-{{.releaseName}}'
      namespace: argocd
      labels:
        app: 'app-{{.app.env.project}}-{{.branch_slug}}-{{.number}}-{{.releaseName}}'
      finalizers:
        - resources-finalizer.argocd.argoproj.io
    spec:
      project: my-dev-envs
      destination:
        namespace: '{{.app.env.cluster.namespace}}'
        server: '{{.app.env.cluster.server}}'
      source:
        repoURL: '{{.app.env.srcRepoURL}}'
        targetRevision: '{{default .app.env.srcTargetRevision .srcTargetRevision}}'
        path: 'apps/{{.type}}-charts/{{.name}}'
        helm:
          releaseName: '{{.releaseName}}'
          values: |
            {{default "" .values}}
          parameters:
            - name: pr_branch
              value: '{{.branch}}'
            - name: pr_branch_slug
              value: '{{.branch_slug}}'
            - name: pr_number
              value: '{{.number}}'
            - name: pr_head_sha
              value: '{{.head_sha}}'
            - name: pr_labels
              value: '{{index .labels 0}}'
      syncPolicy:
        automated:
          allowEmpty: true
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true

The configs/config.yaml file:

app:
  env:
    project: "dev"
    name: "s01"
    servicePhase: "dev"
    infra:
      vendor: "aws"
      accountID: "123456789"
    cluster:
      name: "dev-s01"
      region: "ap-northeast-2"
      server: "https://XXXXXXXXXXXXXXXXXXX.xxx.ap-northeast-2.eks.amazonaws.com"
      namespace: "s01"
    srcRepoURL: "https://github.mycompany.com/myorg/dev-env.git"
    srcTargetRevision: "main"

  charts:
    - releaseName: "secrets"
      name: "externalSecrets"
      type: "pre-required"
      srcTargetRevision: "{{.branch}}"
      values: |
        nameOverride: "dev-configs"
    - releaseName: "etcd"
      name: "etcd"
      type: "general"
      srcTargetRevision: "{{.branch}}"
    - releaseName: "dynamodb-local"
      name: "dynamodb-local"
      type: "general"
      srcTargetRevision: "{{.branch}}"
    - releaseName: "redis"
      name: "redis-cluster"
      type: "general"
      srcTargetRevision: "{{.branch}}"
    - releaseName: "rabbitmq"
      name: "rabbitmq"
      type: "general"
      srcTargetRevision: "{{.branch}}"  

Expected behavior

application set will deploy applications when PR is created.

Version

{
    "Version": "v2.9.3+6eba5be",
    "BuildDate": "2023-12-01T23:05:50Z",
    "GitCommit": "6eba5be864b7e031871ed7698f5233336dfe75c7",
    "GitTreeState": "clean",
    "GoVersion": "go1.21.3",
    "Compiler": "gc",
    "Platform": "linux/amd64",
    "KustomizeVersion": "v5.2.1 2023-10-19T20:13:51Z",
    "HelmVersion": "v3.13.2+g2a2fb3b",
    "KubectlVersion": "v0.24.2",
    "JsonnetVersion": "v0.20.0"
}
Matteo099 commented 9 months ago

I'm encountering the same issue. Are there any updates on its status?

nastacio commented 7 months ago

Thank you for the trick with elements: [], as the instructions don't mention it (probably some pending fix in the code)

I got your example to work with one important change: move the charts element from under app to the top of the YAML file.

mkoval commented 4 months ago

I am also encountering the same issue. Moving the list.elementsYaml generator out to the topmost merge generator fixes the issue, but (unfortunately) breaks the structure that I was trying to implement -- where the {git: {files: [...]}} generator depends on values set by a previous cluster generator.

In contrast to what @nastacio said above, I don't see any difference between:

Did ya'll find a workaround for this?

andrii-korotkov-verkada commented 1 week ago

ArgoCD versions 2.10 and below have reached EOL. Can you upgrade and let us know if the issue is still present, please?

pksukumar commented 1 week ago

@andrii-korotkov-verkada, Facing the same issue in v2.11.8+e7d8b31

pksukumar commented 1 week ago

Like @mkoval suggested, moving matrix generator to the top worked for me,

spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - matrix:
      generators:
        - matrix:
            generators:
            - git: 
                repoURL: git@github.com/xxxxxxx/teleportv2
                revision: HEAD
                files:
                - path: charts/teleport-cluster/prod-me-teleport-tenants.yaml
            - list:
                elements: []
                elementsYaml: "{{ .teleport.tenants | toJson }}"
        - list:
            elements:
            - envType: "production"
              region: "me-central-1"

but this didn't work,

spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - matrix:
      generators:
        - list:
            elements:
            - envType: "production"
              region: "me-central-1"
        - matrix:
            generators:
            - git: 
                repoURL: git@github.com/xxxxxxxx/teleportv2
                revision: HEAD
                files:
                - path: charts/teleport-cluster/prod-me-teleport-tenants.yaml
            - list:
                elements: []
                elementsYaml: "{{ .teleport.tenants | toJson }}"

But this is ok for my usecase.