Search code examples
templateskubernetes-helm

use {{range}} in .Values to generate a list


In helm I have the following .Values

mqtt:
  topics:
    - /tenant/+/#
    - /otherStuff/
    - /importantStuff/

tenants:
  - id: tenantA
    name: Tenant A
  - id: tenantB
    name: Tenant B

Instead of the wildcard topic /tenant/+/# I reather would like to have the topics tenant specific:

  • /tenant/tenantA/#
  • /tenant/tenantB/#

So I tried what would make sense to me should work:

mqtt:
  topics:
{{- range .Values.tenants }}
    - /tenant/{{ .id }}/#
{{ end }}
    - /otherStuff/
    - /importantStuff/

This leads to multiple errors

A block sequence may not be used as an implicit map key
Implicit keys need to be on a single line
Implicit map keys need to be followed by map values

While not completly understanding the errors, it seems to me that this approach does not work or I am doing something completely wrong.

How can I loop in my .Values over a range and generate to generate a list?

Helm Playground (Actually shows a different error as visual studio code does, but probably the same lead)


Solution

  • Helm doesn't allow this. The contents of values.yaml must be a flat YAML file, and no templating is applied to it.

    Helm - Templating variables in values.yaml addresses a simpler case of this for simple strings using the Helm tpl function to render a string. You could do that here, but it's trickier: the values.yaml value must be a string, and you'll have to ask Helm to parse the result of tpl with fromYaml.

    # values.yaml
    mqtt:
      #       v YAML "block scalar" marker to create a multiline string
      topics: |
        {{- range .Values.tenants }}
        - /tenant/{{ .id }}/#
        {{ end }}
        - /otherStuff/
        - /importantStuff/
    #^^^ also note all contents are indented
    
    {{- $topics := tpl .Values.mqtt.topics . | fromYaml }}
    {{- range $topic := $topics }}...{{ end }}