Template complexity: can't evaluate field Values in type interface {}

2 min read

Working with templates can be challenging since, at the end of the day, we are mixing two languages: The template language and the language on which the template itself is written. Doing so we are getting the complexity of one language in addition of the complexity of the other language. That's maybe the main reason why, sometimes, it can be challenging to spot a issues when templates are involved. For example, helm uses templates for generating the appropriate Kubernetes objects, this is one of the errors you might encounter:

$ helm template  . --debug 
install.go:172: [debug] Original chart version: ""
install.go:189: [debug] CHART PATH: /home/pet2cattle/git/spinnaker/helm-spinnaker


Error: template: spinnaker/templates/hooks/install-using-hal.yaml:15:28: executing "spinnaker/templates/hooks/install-using-hal.yaml" at <include (print $.Template.BasePath "/configmap/halyard-config.yaml") .>: error calling include: template: spinnaker/templates/configmap/halyard-config.yaml:120:54: executing "spinnaker/templates/configmap/halyard-config.yaml" at <.Values.serviceAccount.spinnaker.enable>: can't evaluate field Values in type interface {}
helm.go:81: [debug] template: spinnaker/templates/hooks/install-using-hal.yaml:15:28: executing "spinnaker/templates/hooks/install-using-hal.yaml" at <include (print $.Template.BasePath "/configmap/halyard-config.yaml") .>: error calling include: template: spinnaker/templates/configmap/halyard-config.yaml:120:54: executing "spinnaker/templates/configmap/halyard-config.yaml" at <.Values.serviceAccount.spinnaker.enable>: can't evaluate field Values in type interface {}

The error itself looks challenging at first glance, the lines that causes this message are the following:

{{- range $index, $context := .Values.kubeConfig.contexts }}
(...)
    $HAL_COMMAND config provider kubernetes account $PROVIDER_COMMAND {{ $context }} --docker-registries dockerhub \
                --context {{ $context }} {{ if .Values.serviceAccount.spinnaker.enable }}--service-account true{{ end }} \
(...)
{{- end }}

Can you spot the mistake?

On if .Values.serviceAccount.spinnaker.enable:

We need to keep in mind that the dot is context-aware: Inside of a range we are iterating over a .Values.kubeConfig.contexts slice. To be able to access to the Values as usual we need to prefix it with a dollar as follows:

{{- range $index, $context := .Values.kubeConfig.contexts }}
(...)
    $HAL_COMMAND config provider kubernetes account $PROVIDER_COMMAND {{ $context }} --docker-registries dockerhub \
                --context {{ $context }} {{ if $.Values.serviceAccount.spinnaker.enable }}--service-account true{{ end }} \
(...)
{{- end }}

Posted on 02/04/2021