Implementing Template Flow Control

1. Using Conditional Statements

Example: if/else if/else

{{- if eq .Values.env "prod" }}
replicas: 5
{{- else if eq .Values.env "staging" }}
replicas: 2
{{- else }}
replicas: 1
{{- end }}
OperatorMeaning
eq / neEqual / not equal
lt / le / gt / geNumeric comparison
and / or / notBoolean logic

2. Implementing Loops

Example: range over list and map

env:
{{- range .Values.env }}
  - name: {{ .name }}
    value: {{ .value | quote }}
{{- end }}

annotations:
{{- range $key, $value := .Values.annotations }}
  {{ $key }}: {{ $value | quote }}
{{- end }}

3. Using with Scope

Example: Rebind dot

{{- with .Values.image }}
image: "{{ .repository }}:{{ .tag }}"
imagePullPolicy: {{ .pullPolicy }}
{{- end }}
Warning: Inside with, . is rebound. Use $ to access the root, or $.Release.Name.

4. Defining Variables

SyntaxEffect
{{- $name := "myapp" }}Declare variable
{{- $name = "other" }}Reassign (Go template 1.11+)
{{ range $i, $v := .Values.list }}Index + value
$Always refers to root context

5. Checking Value Existence

Example: Safe access patterns

{{- if .Values.tls }}
{{- if .Values.tls.enabled }}
tls: enabled
{{- end }}
{{- end }}

{{/* Or use hasKey */}}
{{- if hasKey .Values "feature" }}
feature: {{ .Values.feature }}
{{- end }}

{{/* Required with custom message */}}
secret: {{ required "secret value is required" .Values.secret }}

6. Using Boolean Logic

ExpressionBehavior
and .a .bTrue if all truthy
or .a .bTrue if any truthy
not .aInvert
and (eq .x 1) (gt .y 0)Group with parens
Note: Empty string, 0, false, nil, empty list/map are all falsy.

7. Comparing Values

FunctionUse
eq a bType + value equality
deepEqual a bRecursive equality (Sprig)
semver "1.2.0" | (semver .Chart.Version).LessThanSemVer comparison
semverCompare ">=1.0.0" .Chart.VersionConstraint match

8. Breaking Loop Iteration

Note: Go templates have no native break/continue. Filter the slice first or use if inside range to skip.
PatternImplementation
Skip items{{- range .items }}{{- if .enabled }}…{{- end }}{{- end }}
Filter then rangePre-process via helper template returning filtered list
Early exitNot supported; refactor to fail on condition

9. Handling Empty Values

Example: Avoid emitting empty fields

{{- with .Values.nodeSelector }}
nodeSelector:
  {{- toYaml . | nindent 2 }}
{{- end }}

{{- if .Values.annotations }}
annotations:
  {{- toYaml .Values.annotations | nindent 2 }}
{{- end }}

10. Using Complex Conditionals

Example: Combined predicate

{{- if and .Values.ingress.enabled (or (eq .Values.env "prod") (eq .Values.env "staging")) }}
{{- include "myapp.ingress" . }}
{{- end }}

11. Implementing Dynamic Resource Creation

Example: Generate one ConfigMap per entry

{{- range $name, $data := .Values.configs }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "myapp.fullname" $ }}-{{ $name }}
  labels: {{- include "myapp.labels" $ | nindent 4 }}
data:
  {{- range $k, $v := $data }}
  {{ $k }}: {{ $v | quote }}
  {{- end }}
{{- end }}