Helm workshop: Templating exercises
Template challenge
Here you’ll be able to practice in order to get familiar with some of the possibilities offered by a templating language.
(pro tip: Don't forget the testing)
These examples may seem useless but the purpose of this is just playing with templates.
1 - "Configuration depends on region"
Create a secret that contains a key 'secret' and a value "myEuropeanSecret". Set an environment variable from this secret only if the value global.region is 'eu-west1' So the first step is to add the values into the values.yaml file.
1global:
2 region: eu-west-1
2 - "Create only if"
Create a job that prints the pod's IP on stdout based on a boolean value printIP.enabled
.
Use the "busybox" image and the command wget -qO - http://ipinfo.io/ip
.
The job should be created only if the value is True, before every other resource has been created (pre-install and pre-upgrade hooks)
3 - "Looping"
Given the following values, create a loop whether in the deployment or in the helpers.tpl file in order to add the environment variables.
1envVars:
2 key1: value1
3 key2: value2
4 key3: value3
4 - "Playing with strings and sprigs"
Add to the "common labels", a new label "codename" with a value composed with the release name, the chart name and the date in the form 20061225. The release name must be at most 3 characters long. The whole string has to be in snakecase.
(you should get something like codename: rel_web_20210215
)
5 - We want to create a list of etcd hosts in the form of "etcd-0,etcd-1,etcd-2" based on a integer that defines the number of etcd hosts
1etcd:
2 count: 5
This list has to be defined in an environment variable ETCD_HOSTS
Proposition of solutions
You should try to find a solution by your own to the above exercises before checking these solutions
1
The following command generates a secrets in the templates directory
1kubectl create secret generic --dry-run=client eu-secret --from-literal=secret='myEuropeanSecret' -o yaml | kubectl neat > templates/secret.yaml
Then we'll enclose the environment variable definition with a condition depending on the region in the deployment template.
1 {{- if eq .Values.global.region "eu-west-1" }}
2 - name: eu-secret
3 valueFrom:
4 secretKeyRef:
5 name: eu-secret
6 key: secret
7 {{- end }}
2
First of all we need to add a new value
1printIP:
2 enabled: True
Then this command will generate a job yaml
1kubectl create job my-ip --dry-run=client --image=busybox -o yaml -- wget -qO - http://ipinfo.io/ip | kubectl neat > templates/job.yaml
If we enclose the whole yaml, it won't be created if the boolean is False. With the hook annotation here, the job will be created before any other resource will be applied. We defined a delete policy "hook-failed" in order to keep the job, otherwise it would have been deleted.
1{{- if .Values.printIP.enabled -}}
2apiVersion: batch/v1
3kind: Job
4metadata:
5 name: my-ip
6 annotations:
7 "helm.sh/hook": pre-install,pre-upgrade
8 "helm.sh/hook-weight": "1"
9 "helm.sh/hook-delete-policy": hook-failed
10...
11{{- end -}}
3
If we want to keep the deployment easy to read, we would prefer adding the code in the _helpers.tpl
1{{/*
2Environment variables
3*/}}
4{{- define "web.envVars" -}}
5{{- range $key, $value := .Values.envVars }}
6- name: {{ $key }}
7 value: {{ $value }}
8{{- end }}
9{{- end -}}
Then this new variable could be used in the deployment as follows
1 env:
2 {{- include "web.envVars" . | nindent 12 }}
4
The common labels can be changed in the file templates/_helpers.tpl. Here's a proposal This one is tricky, I needed to dig back into the charts available in the stable github repository.
1codename: {{ printf "%s %s %s" (.Release.Name | trunc 3) .Chart.Name (now | date "20060102") | snakecase }}
5
Here's an option to achieve the expected results.
1 env:
2 - name: ETCD_HOSTS
3 value: "{{ range $index, $e := until (.Values.etcd.count|int) }}{{- if $index }},{{end}}etcd-{{ $index }}{{- end }}"