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?
In Helm templates, a variable is a named reference to another object. It follows the form $name . Variables are assigned with a special assignment operator: := . We can rewrite the above to use a variable for Release.Name .
The include function allows you to bring in another template, and then pass the results to other template functions. For example, this template snippet includes a template called mytpl , then lowercases the result, then wraps that in double quotes.
The Helm template syntax is based on the Go programming language's text/template package. The braces {{ and }} are the opening and closing brackets to enter and exit template logic.
Helm has over 60 available functions. Some of them are defined by the Go template language itself. Most of the others are part of the Sprig template library.
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 ".".
I will left this here because some people might be trying to set a static value to a variable in Helm to re-use it in a template and they probably will find this SO question by its title. So, here is a trick:
Update:
There's a better way to do this:
{{- $_ := set . "appName" "app_name_one"-}}
---
apiVersion: v1
kind: Deployment
apiVersion: apps/v1beta2
metadata:
name: {{ .appName }}
The old advice (don't use it)
Combined with the syntax from the answer above suggested by @kscoder
---
# values.yml
static_vars:
app_name_one: app_name_one
text_to_reuse: text_to_reuse
---
# templates/deployment.yml
# now you don't need to copy-n-paste values, just set them here once
{{- $text_to_reuse := index .Values "static_vars" "text_to_reuse" -}}
{{- $app_name := index .Values "static_vars" "app_name_one" -}}
{{- $_ := set . "app_name" $app_name -}}
apiVersion: v1
kind: Deployment
apiVersion: apps/v1beta2
metadata:
name: {{ .app_name }}
spec:
selector:
# https://github.com/kubernetes/kubernetes/issues/26202
matchLabels:
name: {{ .app_name }}
template:
metadata:
labels:
name: {{ .app_name }}
name_alt: {{ $app_name }}
other_label: {{ $text_to_reuse }}
# and so on
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