Im trying to iterate over the following values in my helm values.yaml
using a helm helper .tpl
Values:
pubSub:
- topicName: topic-1
topicEnvVar: TOPIC_1
subscriptions:
- subscriptionName: subscription-1
subscriptionEnvVar: SUBSCRIPTION_1
- subscriptionName: subscription-2
subscriptionEnvVar: SUBSCRIPTION_2
- topicName: topic-2
topicEnvVar: TOPIC_2
subscriptions: {}
- topicName: topic-3
topicEnvVar: TOPIC_3
subscriptions: {}
and the helper I’m trying to use is:
{{- range $topic, $envVar := .Values.pubSub }}
- name: {{ $envVar }}
value: {{ $topic.topicName }}
{{- range $subName, $subEnvVar := $topic.subscriptions }}
- name: {{ $subEnvVar }}
value: {{ $subName }}
{{- end }}
{{- end }}
Effectively, I would like it to iterate over the list of maps, and take out the pubs topic name and the topic environment variable name, and output them as:
- name: TOPIC_1
value: topic-1
- name: TOPIC_2
value: topic-2
- name: TOPIC_3
value: topic-3
And the same for the subscriptions:
- name: SUBSCRIPTION_1
value: subscription-1
- name: SUBSCRIPTION_2
value: subscription-2
For context, the list within the values.yaml
is being fed into a helm template for https://marketplace.upbound.io/providers/upbound/provider-gcp/v0.8.0/resources/pubsub.gcp.upbound.io/Subscription/v1beta1 which allows the creation of GCP pubs items via K8s resources.
When running a helm template . --debug
, I can see that my k8s resource creates as expected, however when it’s trying to go through the steps of creating the list which I will be using in the env
block of the deployment.yaml (helper seen above), it bombs out with:
Error: template: chart/templates/deployment.yaml:38:16: executing "chart/templates/deployment.yaml" at <include "chart.envVarsFull" .>: error calling include: template: chart/templates/_envVarsHelper.tpl:77:18: executing "chart.envVarsFull" at <$topic.topicName>: can't evaluate field topicName in type int
helm.go:84: [debug] template: chart/templates/deployment.yaml:38:16: executing "chart/templates/deployment.yaml" at <include "chart.envVarsFull" .>: error calling include: template: chart/templates/_envVarsHelper.tpl:77:18: executing "chart.envVarsFull" at <$topic.topicName>: can't evaluate field topicName in type int
Would anyone know how I can structure my helper config correctly to allow me to output as I’m expecting? 😀
Cheers!
.Values.pubSub
is a list. If you run a range
loop over that and assign two variables, the variables are the zero-based index and list item. It does not try to rebind variables based on the contents of the list item.
One thing you could do to see this is to print out the items directly
{{- range $index, $item := .Values.pubSub -}}
# {{ $index }}: {{ $item.topicName }}
{{ end -}}
which will print out
# 0: topic-1
# 1: topic-2
# 2: topic-3
The easiest way to fix this is to just use a single value assignment in the range
loop. This will get assigned the loop item.
{{- range $topic := .Values.pubSub -}}
- name: {{ $topic.topicEnvVar }}
value: {{ $topic.topicName }}
{{ end -}}
You could also take advantage of range
rebinding the .
special variable and not assign a variable at all.
{{- range .Values.pubSub -}}
- name: {{ .topicEnvVar }}
value: {{ .topicName }}
{{ range .subscriptions -}}
- name: {{ .subscriptionEnvVar }}
value: {{ .subscriptionName }}
{{ end -}}
{{- end -}}
range
is part of the core Go text/template
language, and its behavior is documented in the text/template
package documentation.