argoproj / argo-cd

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

Application/ApplicationSet: add support for templated helm value files #16302

Open theblop opened 12 months ago

theblop commented 12 months ago

Summary / Motivation

One annoying thing with helm values in values files is that they can't refer to other helm values.

With ApplicationSets it's possible to template them when defined inline in spec.template.helm.values, but that implies all applications use the same values template.

I suggest adding the possibility to use go-templated values files in Application definitions (e.g. spec.template.helm.valueFilesTemplates) or even a new tpl function available for go templates inside ApplicationSet (similar to the same helm function).

Proposal

Possible implementation with a valueFilesTemplates helm option in the Application definition:

ApplicationSet (partial):

kind: ApplicationSet
spec:
  generators:
  - matrix:
      generators:
      - git:
          repoURL: https://example.com
          files:
            - path: "apps/*.yaml"
      - list:
          elements:
            - domainname: example1.com
            - domainname: example2.com

  goTemplate: true
  template:
    metadata:
      name: {{ .appname }}
    spec:
      project: myproject
      sources:
        - repoURL: https://example.com
          path: app/{{ .appname }}
          helm:
            valueFilesTemplates:
              - app/{{ .appname }}/values.yaml.gotmpl

Files in git repo:

apps/app01.yaml:

appname: app01
hostname: foo

app/app01/values.yaml.gotmpl:

ingress:
  tls:
    - hosts:
      - '{{ .hostname }}.{{ .domainname }}'
  hosts:
    - '{{ .hostname }}.{{ .domainname }}'

Another possibility might be to add a tpl function in the argocd templating functions, similar to helm in templates files:

  ...
  template:
    spec:
      sources:
        -  helm:
            values: |
              {{ .values_string_from_generator | tpl | nindent 14 }}
crenshaw-dev commented 11 months ago

Isn't it possible in Helm for one values file to template values from another values file?

theblop commented 11 months ago

Isn't it possible in Helm for one values file to template values from another values file?

Sadly not and yaml anchor/reference tricks can't replace a value mid-text. Only helmfile supports templating values (https://helmfile.readthedocs.io/en/latest/#values-files-templates) and this is what I currently use as an Argo plugin, but it has a lot of limitations compared to what the native argo helm source supports (plugins don't support multi-sources values for a start, I would have to re-implement that inside the plugin).

It would be nice to have that functionality in argo (getting the template from a generator)

diversario commented 11 months ago
          helm:
            valueFilesTemplates:
              - app/{{ .appname }}/values.yaml.gotmpl

would be fantastic. Sometimes values files are huge blobs of text that contain one dynamic string (e.g. the cluster name), and currently it's just impossible to avoid massive amounts of copypaste because the entire values file has to be duplicated for every cluster.

            values: |
              {{ .values_string_from_generator | tpl | nindent 14 }}

is also nice.

theblop commented 8 months ago

@crenshaw-dev as a quick and hopefully not too complex implementation, do you think it would be relatively easy to just add the same tpl function as in helm in the Argo gotemplate syntax used in ApplicationSets?

That would allow me to get rid of the helmfile plugin I'm currently using to implement templating of helm values :)

chary1112004 commented 7 months ago

Currently, to work around we need call nested application and then start using tpl. We expect no need calling to nested application to generate value using tpl

first application call to nested application and nested application is as below:

apiVersion: argoproj.io/v1alpha1
kind: Application
...
spec:
  # The project the application belongs to.
  project: bootstrap

  # Source of the application manifests
  source:
    repoURL: <repo>
    targetRevision: <tag>
    path: test
    helm:
      values: |-
        common:
        {{ tpl (.Values.common | toYaml) . | nindent 10 }}
luhahn commented 6 months ago

This really would be a great feature for argocd

bingkunyangvungle commented 2 months ago

Any updates on this one? It can provide so much flexibility for rendering.