Skip to content

Templating in Helm Values Files

Issue

Helm does not support templating within values files, even though it can significantly improve the readability and maintainability of charts in some cases.

For example, default values might depend on other values or chart metadata.

Solution

  • A helper template is included in each chart template to expand the values (unfortunately, Helm does not support pre-render hooks to run a template first).
  • The template recursively applies the tpl function to values until no further changes occur
  • The number of iterations is limited. If the limit is exceeded, templating fails to prevent infinite loops caused by circular references.

Template

{{- define "template-values" -}}
  {{- /* Default values */ -}}
  {{- $ := . -}}
  {{- $depth := 20 -}}
  {{- $subcall := false  -}}

  {{- /* Extra args are passed (by user or with sub call) */ -}}
  {{- if kindIs "slice" . }}
    {{- $ = index . 0 -}}
    {{- $depth =  index . 1 -}}
    {{- if gt (len .) 2 -}}
      {{- $subcall = ( index . 2)  -}}
    {{- end }}
  {{- end -}}

  {{- /* Skip if already templated */ -}}
  {{- if not (hasKey $ "__valuesAreTemplated")  -}}

    {{- $original := $.Values | toYaml  -}}
    {{- $templated := ""  -}}

    {{- /* Apply tpl to current values */ -}}
    {{- with $ -}}{{- $templated = tpl $original $  -}}{{- end -}}
    {{- $_ := set $ "Values" ($templated | fromYaml) -}}

    {{- /* Execute next iteration if values have changed with templating */ -}}
    {{- if $templated | ne  $original -}}
      {{- if gt $depth 0  -}}
        {{- include "template-values" (list $ ( sub $depth 1) true) }}
      {{- else -}}
        {{- fail "Failed to template Values, likely recursive values dependencies" -}}
      {{- end -}}
    {{- end -}}

    {{- if not $subcall }}
      {{- /* Mark values as already templated */ -}}
      {{- $_ := set $ "__valuesAreTemplated" true -}}
    {{- end -}}

  {{- end -}}

{{- end -}}

Usage

  • Add {{- include "template-values" $ -}} near the top of each chart template file (before any values are accessed), to ensure templated values are processed.
  • Define templated values as needed in your values.yaml. Example:
    value1: "{{ .Values.value2 }}"
    value2: "test"
    chartName: "{{ .Chart.Name }} v{{ .Chart.Version }}"
    

Note

Optionally, you can override the maximum number of templating iterations (default is 20):

{{- include "template-values" (list $ 30) -}} 

Limitations

  • All templated values are interpreted and expanded as strings, even if the intended result is a number, boolean, list, or map.
  • Helm renders dependency charts before the parent chart, so this approach does not work when a parent chart attempts to template dependency values.

Comments