Go template syntax, built-in objects, control structures, functions, and whitespace control.
.Values, .Release, .Chart, .Capabilities, .Templateif/else, with, rangeHelm templates are YAML files with Go template actions enclosed in double curly braces.
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-config
namespace: {{ .Release.Namespace }}
data:
environment: {{ .Values.env | default "production" | quote }}
version: {{ .Chart.AppVersion }}
Functions chain together with the | (pipe) operator, flowing left to right — just like Unix pipes.
# value flows: .Values.env -> default -> quote
environment: {{ .Values.env | default "production" | quote }}
Every Helm template has access to five top-level objects:
| Object | Description | Common Fields |
|---|---|---|
.Values | User-supplied values from values.yaml and --set | .Values.replicaCount, .Values.image.tag |
.Release | Metadata about the current release | .Release.Name, .Release.Namespace, .Release.IsInstall, .Release.IsUpgrade |
.Chart | Contents of Chart.yaml | .Chart.Name, .Chart.Version, .Chart.AppVersion |
.Capabilities | Cluster capabilities | .Capabilities.KubeVersion, .Capabilities.APIVersions |
.Template | Current template info | .Template.Name, .Template.BasePath |
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}
{{- else }}
# Ingress disabled
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 2 }}
{{- end }}
with re-scopes . to the value, and skips the block if the value is empty.
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
| Function | Purpose | Example |
|---|---|---|
default | Fallback value | {{ .Values.port | default 8080 }} |
quote | Wrap in double quotes | {{ .Values.env | quote }} |
toYaml | Marshal to YAML string | {{ toYaml .Values.labels | nindent 4 }} |
nindent | Newline + indent N spaces | {{ toYaml . | nindent 6 }} |
indent | Indent N spaces (no newline) | {{ toYaml . | indent 4 }} |
upper / lower | Case conversion | {{ .Values.env | upper }} |
trim | Strip leading/trailing whitespace | {{ .Values.name | trim }} |
required | Fail if value is empty | {{ required "image.tag is required" .Values.image.tag }} |
Go templates preserve all whitespace outside actions. Use trim markers ({{- and -}}) to eat adjacent whitespace.
metadata:
labels:
{{ if .Values.team }}
team: {{ .Values.team }}
{{ end }}
app: myapp
Produces blank lines above and below the conditional.
metadata:
labels:
{{- if .Values.team }}
team: {{ .Values.team }}
{{- end }}
app: myapp
Clean output — no extra blank lines.
{{- trims whitespace before the action. -}} trims whitespace after. Use helm template frequently to check your output.Putting it all together — a Deployment template using values, conditionals, range, and pipelines:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-app
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount | default 1 }}
selector:
matchLabels:
app.kubernetes.io/instance: {{ .Release.Name }}
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
{{- range .Values.ports }}
- containerPort: {{ .port }}
protocol: {{ .protocol | default "TCP" }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{ }} — everything outside is literal YAML.|) chain functions left-to-right for concise transformations.if, with, range) drive conditional and iterative logic.{{- / -}} is essential for clean YAML output.helm template . during development.