Helm Templates


General

Templates generate manifest files, which are YAML-formatted resource descriptions that Kubernetes can understand. 

https://helm.sh/docs/chart_template_guide/

Create chart.

helm create mychart && cd mychart
  • Chart.yaml file contains a description of the chart
  • charts/ directory may contain other charts
  • templates/ directory is for template files
    • templates/NOTES.txt: The “help text” for your chart. This will be displayed to your users when they run helm install.
    • templates/deployment.yaml: A basic manifest for creating a Kubernetes deployment
    • templates/service.yaml: A basic manifest for creating a service endpoint for your deployment
    • templates/_helpers.tpl: A place to put template helpers that you can re-use throughout the chart
  • values.yaml – contains the default values for a chart
tree
.
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│   └── test-connection.yaml
└── values.yaml

Delete everything within the templates directory.

rm -rf templates/*

Create a configmap.

cat <<EOF > templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World" EOF

Run template to view the manifests.

The template command renders the chart locally and displays the output.

helm template .
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"

Run install.

helm install mychart .
NAME: mychart
LAST DEPLOYED: Thu Jun 16 14:04:49 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

Get configmap.

kubectl get configmap -l app.kubernetes.io/managed-by=Helm
NAME DATA AGE
mychart-configmap 1 77s

Run get.

helm get manifest mychart
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"

Uninstall.

helm uninstall mychart

Update configmap with Release.Name.

cat <<EOF > templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World" EOF

Run template.

Notice the release name is inserted into the configmap name.

helm template mycoolchart .
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mycoolchart-configmap
data:
myvalue: "Hello World"

Run install with debug and dryrun.

helm install mycoolchart . --debug --dry-run
install.go:178: [debug] Original chart version: ""
install.go:195: [debug] CHART PATH: /Users/tommy/helm/mychart

NAME: mycoolchart
LAST DEPLOYED: Thu Jun 16 14:46:49 2022
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
autoscaling:
enabled: false
maxReplicas: 100
minReplicas: 1
targetCPUUtilizationPercentage: 80
fullnameOverride: ""
image:
pullPolicy: IfNotPresent
repository: nginx
tag: ""
imagePullSecrets: []
ingress:
annotations: {}
className: ""
enabled: false
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
nameOverride: ""
nodeSelector: {}
podAnnotations: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:
port: 80
type: ClusterIP
serviceAccount:
annotations: {}
create: true
name: ""
tolerations: []

HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mycoolchart-configmap
data:
myvalue: "Hello World"

Built-in Objects

https://helm.sh/docs/chart_template_guide/builtin_objects/

A few common objects.

  • {{ .Release.Name }}
  • {{Release.Namespace}}
  • {{Release.Revision}}
  • {{.Chart.Name}}-{{.Chart.Version}}

Create chart.

helm create built-in-objects && cd built-in-objects

Delete everything within the templates directory.

rm -rf templates/*

Create a configmap with a few of the built-in options.

cat <<EOF > templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
namespace: {{ .Release.Namespace }}
data:
objects.properties: |
chart-name: {{ .Chart.Name }}
chart-version: {{ .Chart.Version }}
release-namespace: {{ .Release.Namespace }}
release-revision: {{ .Release.Revision }} EOF

Run template to view the manifests.

The template command renders the chart locally and displays the output.

helm template built-in-objects . --namespace itsmetommy
---
# Source: built-in-objects/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: built-in-objects-configmap
namespace: itsmetommy
data:
objects.properties: |
chart-name: built-in-objects
chart-version: 0.1.0
release-namespace: itsmetommy
release-revision: 1

Install.

helm install built-in-objects . --namespace itsmetommy

Get.

kubectl get configmaps -n itsmetommy built-in-objects-configmap -oyaml
apiVersion: v1
data:
objects.properties: |
chart-name: built-in-objects
chart-version: 0.1.0
release-namespace: itsmetommy
release-revision: 1
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: built-in-objects
meta.helm.sh/release-namespace: itsmetommy
creationTimestamp: "2022-06-19T01:08:38Z"
labels:
app.kubernetes.io/managed-by: Helm
name: built-in-objects-configmap
namespace: itsmetommy
resourceVersion: "1251089"
uid: ab18603d-0dff-4c41-ac11-c87924d11839

Uninstall.

helm uninstall built-in-objects -n itsmetommy

Values Files

https://helm.sh/docs/chart_template_guide/values_files/

Note: helm always includes values.yaml by default.

Create chart.

helm create values-files && cd values-files

Delete everything within the templates directory.

rm -rf templates/*

Update values.yaml.

echo 'favoriteDrink: coffee' > values.yaml

Create a configmap.

cat <<EOF > templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favoriteDrink }} EOF

Run template.

helm template values-files .
---
# Source: values-files/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: values-files-configmap
data:
myvalue: "Hello World"
drink: coffee

We can easily override that by adding a –set flag.

helm template values-files --set favoriteDrink=slurm .
---
# Source: values-files/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: values-files-configmap
data:
myvalue: "Hello World"
drink: slurm

Values files can also contain more structured content.

cat <<EOF > values.yaml
favorite:
  drink: coffee
  food: pizza
EOF

Update configmap.

cat <<EOF > templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink }}
food: {{ .Values.favorite.food }}
EOF

Run template.

helm template values-files .
---
# Source: values-files/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: values-files-configmap
data:
myvalue: "Hello World"
drink: coffee
food: pizza

Flow Control

https://helm.sh/docs/chart_template_guide/control_structures/

if/else

Create chart.

helm create flow-control && cd flow-control

Delete everything within the templates directory.

rm -rf templates/*

Create deployment.

cat <<EOF > templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flow-control-{{ .Values.env }}
labels:
app: {{ .Release.Name }}
env: {{ .Values.env }}
spec:
selector:
matchLabels:
app: {{ .Release.Name }}
env: {{ .Values.env }}
{{- if eq .Values.env "prod" }}
replicas: 3
{{- else }}
replicas: 1
{{- end }}
template:
metadata:
labels:
app: {{ .Release.Name }}
env: {{ .Values.env }}
spec:
containers:
- name: hello-app
image: gcr.io/google-samples/hello-app:1.0
ports:
- containerPort: 8080 EOF

Create values.yaml.

echo 'env: staging' > values.yaml

Run template (the default is staging).

helm template flow-control-staging .
---
# Source: flow-control/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flow-control-staging
labels:
app: flow-control-staging
env: staging
spec:
selector:
matchLabels:
app: flow-control-staging
env: staging
replicas: 1
template:
metadata:
labels:
app: flow-control-staging
env: staging
spec:
containers:
- name: hello-app
image: gcr.io/google-samples/hello-app:1.0
ports:
- containerPort: 8080

Run template, but override env as prod.

helm template flow-control . --set env=prod
---
# Source: flow-control/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flow-control-prod
labels:
app: flow-control-prod
env: prod
spec:
selector:
matchLabels:
app: flow-control-prod
env: prod
replicas: 3
template:
metadata:
labels:
app: flow-control-prod
env: prod
spec:
containers:
- name: hello-app
image: gcr.io/google-samples/hello-app:1.0
ports:
- containerPort: 8080

Install.

helm install flow-control-prod . --set env=prod

Get.

kubectl get deploy flow-control-prod -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
meta.helm.sh/release-name: flow-control-prod
meta.helm.sh/release-namespace: default
creationTimestamp: "2022-06-19T01:40:48Z"
generation: 1
labels:
app: flow-control-prod
app.kubernetes.io/managed-by: Helm
env: prod
name: flow-control-prod
namespace: default
resourceVersion: "1253554"
uid: 8a7e9fa1-0d3e-48dd-aeb7-e34eb70dd52c
spec:
progressDeadlineSeconds: 600
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: flow-control-prod
env: prod
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: flow-control-prod
env: prod
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: IfNotPresent
name: hello-app
ports:
- containerPort: 8080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 3
conditions:
- lastTransitionTime: "2022-06-19T01:40:49Z"
lastUpdateTime: "2022-06-19T01:40:49Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2022-06-19T01:40:48Z"
lastUpdateTime: "2022-06-19T01:40:49Z"
message: ReplicaSet "flow-control-prod-76bd56674f" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 1
readyReplicas: 3
replicas: 3
updatedReplicas: 3
kubectl get po
NAME READY STATUS RESTARTS AGE
flow-control-prod-76bd56674f-ms7gf 1/1 Running 0 32s
flow-control-prod-76bd56674f-phqkl 1/1 Running 0 32s
flow-control-prod-76bd56674f-zw2zb 1/1 Running 0 32s

Uninstall.

helm uninstall flow-control-prod

This should be enough to get you started.