I have a generic template for a k8s resource that I want to expand n times (if you are curious, it is so that I can create n members of a mongo cluster and they are using the statefulset resource so that each member has a stable network name).
Obviously I need different values each time through the loop. I am looping over a series of indices generated by the Sprig "until" function. But the $index for the loop does not get set in the "." namespace. So I am unable to refer the the current iteration inside of my defined template in my _helpers.tpl file.
here is an example template w/full k8s resource yaml (I'm abbreviating most of it):
{{- define "mytest" -}}
---
apiVersion: apps/v1beta1
kind: StatefulSet
abbreviated...
containers:
- name: mongod-$index
abbreviated...
{{- end -}}
caller:
{{ range $index, $e := until .Values.mongod_count }}
{{include "mytest" .}}
{{ end}}
I just get: undefined variable "$index"
I have tried with blocks too, like this in my (caller) template:
{{ $foo := "somevalue" }}
{{ define "my_extra_labels" }} bla {{ .Values.test }}_{{$foo}}{{end}}
{{ template "mytest" . }}
And this in my _helpers.tpl
{{/* Test stuff */}}
{{- define "mytest" -}}
hello: world_how_are_{{ block "my_extra_labels" . }}{{ end }}
{{- end -}}
The variable $foo is not defined in the "define" body.
This template scoping feels so restrictive that at this point I can't see how to use it to solve my current scenario.
Is there some way to shove variables into the "." namespace? And if so (crossing my fingers) is there a way to merge namespaces in some way so that I can still access .Values and .Chart variables?
Templates in helm cannot access variables. However, the context handed to the template is a dictionary. The sprig library is accessible from within the Go templates and can be used to manipulate dictionaries.
Take this simplified template:
{{- define "mytest" -}}
- name: mongod-{{ .index }}
{{- end -}}
You can now call this template as an example:
{{ range $index := until 5 }}
{{- $p := dict "index" $index }}
{{include "mytest" $p}}
{{- end -}}
This will output:
- name: mongod-0
- name: mongod-1
- name: mongod-2
- name: mongod-3
- name: mongod-4
You can also add items to an existing or the current scoped dictionary:
{{- $_ := set . "index" "none" }}
{{include "mytest" .}}
The $_ is used to suppress undesired output as "set" returns the new dictionary. The above returns:
- name: mongod-none
Any values added to the dictionary will live beyond the call. If you want to avoid polluting an existing dictionary you can force a deep copy with:
{{- $d := merge (dict) . -}}
Anything added to "$d" will not exist in ".".