In a helm chart want to iterate over a map that contains structured values.
I do know how to iterate over a map with simple string values. I also can iterate over an array that contains structured values (not shown here). But I did not manage to iterate over a map that contains structured values.
This is my directory structure containing 3 files:
templates/test.yaml
Chart.yaml
values.yaml
A simple file Chart.yaml (just for completing the showcase):
---
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: foochart
version: 0.1.0
The file values.yaml with a map that contains simple string values (label) and one that contains structured values (label1):
---
label:
fook: foo
bark: bar
label1:
fook:
name: foo
value: foo1
bark:
name: bar
value: bar2
This template test.yaml works:
---
env:
{{- range $k, $v := .Values.label }}
- name: {{ $k }}
value: {{ $v }}
{{- end }}
But when I substitute .Values.label
by .Values.label1
, it produces no output.
This is my command for testing:
helm template foochart
Question: Is it possible to process a map with structured values? I would like to use something like $v.name
. If yes, how can I do that?
You can in fact use syntax like $v.name
, if you know that $v
is a variable holding an object.
env:
{{- range $k, $v := .Values.label1 }}
- name: {{ $k }}_{{ $v.name }}
value: {{ $v.value }}
{{- end }}
If you know that it has exactly the syntax you want, there is an underdocumented toYaml
function that takes an arbitrary object and returns it as unindented YAML. In your example, each of the values has the form of an env:
item, and if you know (or specify) that, you can write out literally:
env:
{{- range .Values.label1 }}
- {{ . | toYaml | indent 4 | trim }}
{{- else }}
[]
{{- end }}
(In this last example: I'm not assigning a variable, so .
is temporarily reassigned to each value in the map, and the keys are lost; for each item, I convert it to YAML, indent it by 4 spaces, but then trim out leading and trailing whitespace; and if there are no values, I explicitly write out an empty list.)
It's usually easier to specify a format you want your values to be in, and work with that. If you for some reason can't be sure which form you have, the template language includes functions to test on a value's type, so in principle you can test:
env:
{{- range $k, $v := .Values.labelN }}
{{- if kindIs "string" $v }}
- name: {{ $k }}
value: {{ $v }}
{{- else }}
- name: {{ $v.name }}
value: {{ $v.value }}
{{- end }}
{{- else }}
[]
{{- end }}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With