Helm Templates: A Practical Reference
Luke Hebert
- 7 minutes read - 1356 wordsA comprehensive reference for writing and debugging Helm chart templates. This cheatsheet covers the essential functions, syntax, and patterns you will encounter in most Helm charts, from basic template delimiters and built-in objects to control structures, file operations, and advanced helpers. Use it as a quick lookup while writing or troubleshooting templates.
Common Gotchas
- YAML Indentation: Always use
nindentfor proper indentation. - Quotes: Use the
quotefunction for string values that might contain special characters. - Empty Values: Use
defaultorrequiredfor missing values. - Scope: Remember that the
.context changes insidewithandrange. - Whitespace: Use
{{-and-}}to control whitespace. - Type Conversion: Convert types explicitly when needed.
Template Cheatsheet
Basic Template Syntax
Template Delimiters
{{ .Values.image.repository }} # Action - outputs value
{{- if .Values.enabled }} # Action with left whitespace trimming
{{ .Values.name -}} # Action with right whitespace trimming
{{- .Values.name -}} # Action with both sides trimming
{{/* This is a comment */}} # Comment blockVariables and Assignment
{{- $name := .Values.name }}
{{- $replicas := .Values.replicaCount | default 1 }}
{{ $root := . }} # Store root contextBuilt-in Objects
Root Objects
{{ .Release.Name }} # Release name
{{ .Release.Namespace }} # Release namespace
{{ .Release.Service }} # Service that rendered the template (Helm)
{{ .Chart.Name }} # Chart name from Chart.yaml
{{ .Chart.Version }} # Chart version from Chart.yaml
{{ .Values }} # Values from values.yaml and --set
{{ .Files }} # Access to non-template files
{{ .Capabilities }} # Kubernetes cluster capabilities
{{ .Template.Name }} # Current template name
{{ .Template.BasePath }} # Path to current templateCapabilities Object
{{ .Capabilities.APIVersions.Has "apps/v1" }}
{{ .Capabilities.KubeVersion.Major }}
{{ .Capabilities.KubeVersion.Minor }}
{{ .Capabilities.KubeVersion.GitVersion }}Template Functions
String Functions
{{ .Values.name | upper }} # Convert to uppercase
{{ .Values.name | lower }} # Convert to lowercase
{{ .Values.name | title }} # Title case
{{ .Values.name | quote }} # Add quotes
{{ .Values.name | squote }} # Add single quotes
{{ .Values.name | repeat 3 }} # Repeat string
{{ .Values.name | trunc 10 }} # Truncate to 10 chars
{{ .Values.name | trimSuffix "-" }} # Remove suffix
{{ .Values.name | trimPrefix "app-" }} # Remove prefix
{{ printf "%s-%s" .Release.Name .Chart.Name }} # Format string
{{ .Values.name | default "nginx" }} # Default value
{{ .Values.name | required "name is required" }} # Required valueType Conversion
{{ .Values.port | toString }} # Convert to string
{{ .Values.count | int }} # Convert to integer
{{ .Values.enabled | toString }} # Convert boolean to stringList Functions
{{ list "a" "b" "c" }} # Create list
{{ .Values.list | first }} # First item
{{ .Values.list | last }} # Last item
{{ .Values.list | rest }} # All but first
{{ .Values.list | initial }} # All but last
{{ .Values.list | reverse }} # Reverse list
{{ .Values.list | uniq }} # Remove duplicates
{{ .Values.list | sortAlpha }} # Sort alphabetically
{{ .Values.list | join "," }} # Join with separator
{{ has "item" .Values.list }} # Check if list contains itemDictionary Functions
{{ .Values.config | keys }} # Get dictionary keys
{{ .Values.config | values }} # Get dictionary values
{{ pick .Values "key1" "key2" }} # Pick specific keys
{{ omit .Values "key1" "key2" }} # Omit specific keys
{{ merge .Values.override .Values.default }} # Merge dictionariesLogic Functions
{{ and .Values.enabled .Values.ready }} # Logical AND
{{ or .Values.dev .Values.staging }} # Logical OR
{{ not .Values.disabled }} # Logical NOT
{{ eq .Values.env "production" }} # Equal
{{ ne .Values.env "development" }} # Not equal
{{ lt .Values.replicas 5 }} # Less than
{{ le .Values.replicas 5 }} # Less than or equal
{{ gt .Values.replicas 1 }} # Greater than
{{ ge .Values.replicas 1 }} # Greater than or equalControl Structures
Conditionals
{{- if .Values.enabled }}
enabled: true
{{- else if .Values.disabled }}
enabled: false
{{- else }}
enabled: unknown
{{- end }}Inline Conditional
{{ .Values.enabled | ternary "yes" "no" }}Loops
Range over list:
{{- range .Values.items }}
- name: {{ . }}
{{- end }}Range with index and value:
{{- range $index, $value := .Values.items }}
- index: {{ $index }}
value: {{ $value }}
{{- end }}Range over dictionary:
{{- range $key, $value := .Values.config }}
{{ $key }}: {{ $value }}
{{- end }}With (Scope)
{{- with .Values.database }}
host: {{ .host }}
port: {{ .port }}
{{- else }}
# Default database config
host: localhost
port: 5432
{{- end }}Common Patterns
Labels and Selectors
Common labels helper:
{{- define "myapp.labels" -}}
helm.sh/chart: {{ include "myapp.chart" . }}
{{ include "myapp.selectorLabels" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "myapp.selectorLabels" -}}
app.kubernetes.io/name: {{ include "myapp.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}Usage:
metadata:
labels:
{{- include "myapp.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
{{- include "myapp.selectorLabels" . | nindent 6 }}Resource Names
{{- define "myapp.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}Environment Variables
env:
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- if .Values.envFrom }}
envFrom:
{{- range .Values.envFrom }}
- secretRef:
name: {{ .secretRef.name }}
{{- end }}
{{- end }}File Operations
Reading Files
{{ .Files.Get "config.yaml" }} # Read file content
{{ .Files.GetBytes "binary-file" | b64enc }} # Read and base64 encodeFile Globbing
{{- range $path, $content := .Files.Glob "configs/*" }}
{{ $path }}: |
{{ $content | indent 2 }}
{{- end }}ConfigMap from Files
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "myapp.fullname" . }}-config
data:
{{- (.Files.Glob "configs/*").AsConfig | nindent 2 }}Advanced Functions
Encoding Functions
{{ .Values.data | b64enc }} # Base64 encode
{{ .Values.data | b64dec }} # Base64 decode
{{ .Values.password | sha256sum }} # SHA256 hashDate Functions
{{ now | date "2006-01-02" }} # Current date
{{ dateInZone "2006-01-02" (now) "UTC" }} # Date in timezoneLookup Function (Helm 3.2+)
{{ lookup "v1" "Secret" .Release.Namespace "my-secret" }}
{{- if lookup "v1" "Secret" .Release.Namespace "my-secret" }}
# Secret exists
{{- end }}Template Helpers
Named Templates
{{/* Define a template */}}
{{- define "myapp.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/* Use the template */}}
{{ include "myapp.name" . }}
{{/* Use with nindent for proper indentation */}}
labels:
{{- include "myapp.labels" . | nindent 4 }}Template Includes vs Template
include: renders template and passes result through pipeline
{{- include "myapp.labels" . | nindent 4 }}template: renders template directly (deprecated in favor of include)
{{- template "myapp.labels" . }}Best Practices
Whitespace Control
Good, removes extra newlines:
{{- if .Values.enabled }}
enabled: true
{{- end }}Bad, creates empty lines:
{{ if .Values.enabled }}
enabled: true
{{ end }}Indentation
Use nindent for proper YAML indentation:
spec:
template:
metadata:
labels:
{{- include "myapp.labels" . | nindent 8 }}
spec:
containers:
{{- toYaml .Values.containers | nindent 8 }}Required Values
Make values required:
image: {{ .Values.image.repository | required "image.repository is required" }}
tag: {{ .Values.image.tag | required "image.tag is required" }}Type Safety
Convert and validate types:
replicas: {{ .Values.replicaCount | int }}
enabled: {{ .Values.enabled | toString }}Debugging Templates
Render templates without installing:
helm template myapp ./mychartRender specific templates:
helm template myapp ./mychart -s templates/deployment.yamlDebug with values:
helm template myapp ./mychart --debug --dry-runShow computed values:
helm get values myappLint templates:
helm lint ./mychart