Search code examples
kubernetes-helm

Using a defined helper as an iteration for a range


While recently writing a helm chart, I ran into an issue that I couldn't find a solution to.

Basically, I am trying to range off of a defined value (labels), but appear to be running into an issue because the defined value is a string and not a map. I tried to convert it with toYaml to no avail:

{{- range $key, $value := ( include "myChart.selectorLabels" . | toYaml ) }}
- key: {{ $key }}
  operator: In
  values:
  - {{ $value }}
{{- end }}

Example error with toYaml:

COMBINED OUTPUT:
  Error: Failed to render chart: exit status 1: Error: template: myApp/templates/deployment.yaml:103:77: executing "myApp/templates/deployment.yaml" at <toYaml>: range can't iterate over |-
    app.kubernetes.io/name: myApp
    app.kubernetes.io/instance: env-myApp
    conf-sha: 0b92fad469486fedb6ad012c1b5f22c

Example error without toYaml (note lack of linebreak before first value):

COMBINED OUTPUT:
  Error: Failed to render chart: exit status 1: Error: template: myApp/templates/deployment.yaml:103:73: executing "myApp/templates/deployment.yaml" at <.>: range can't iterate over app.kubernetes.io/name: myApp
  app.kubernetes.io/instance: env-myApp
  conf-sha: 0b92fad469486fedb6ad012c1b5f22c

Expected render:

- key: app.kubernetes.io/name
  operator: In
  values:
  - myApp
- key: app.kubernetes.io/instance
  operator: In
  values:
  - env-myApp
- key: conf-sha
  operator: In
  values:
  - 0b92fad469486fedb6ad012c1b5f22c

I think there must be a more elegant solution to this in helm's templating that I am missing.


Solution

  • Helm has two extension functions to convert between strings and complex YAML structures. You're calling toYaml which takes an arbitrary object and serializes it to a YAML string. What you actually have is the string result from include which happens to be parseable YAML, and you need the opposite function, fromYaml.

    {{- range $key, $value := ( include "myChart.selectorLabels" . | fromYaml ) }}
    {{/*-                                                 not toYaml ^^^^     */}}
    

    Neither function is especially well-documented. They are specific to Helm. There are corresponding toJson and fromJson that work similarly.