Render a chart value with a default fallback in a Helm template
A Deployment template sets the container image tag from .Values.image.tag, but the chart must still render when a user does not set that value — it should fall back to the chart's own appVersion. Fill in the template expression so the tag is the user's value when provided and .Chart.AppVersion otherwise.
Constraint: do not hard-code a tag, and the chart must install with zero overrides.
# templates/deployment.yaml
spec:
template:
spec:
containers:
- name: app
image: "myrepo/app:{{ /* TODO: value with default fallback */ }}"
Complete the template expression.
Use Helm's default function: {{ .Values.image.tag | default .Chart.AppVersion }}. It renders .Values.image.tag when the user sets it and falls back to the chart's appVersion when empty or unset. The chart stays installable with zero overrides while still letting a user pin a tag.
- ✗Piping the arguments to
defaultin the wrong order, inverting precedence - ✗Using
required, which aborts rendering instead of falling back - ✗Assuming Go templates have a
?:ternary for defaulting a value
- →How would you instead make the value mandatory, failing the render if it is unset?
- →What does
defaultreturn when.Values.image.tagis an empty string versus nil?
Solution
Helm's default returns its second argument (the fallback) when the left input is empty or unset. Order matters — the user's preferred value goes on the left, the default on the right:
# templates/deployment.yaml
spec:
template:
spec:
containers:
- name: app
image: "myrepo/app:{{ .Values.image.tag | default .Chart.AppVersion }}"
Now helm install with no overrides takes the tag from Chart.yaml (appVersion), while a user can still pin their own tag via --set image.tag=... or values.yaml. Do not use required (it aborts the render), and do not reach for a ternary — Go templates have none.