I am facing an odd behaviour of helm when using the range
iterator. My template looks like something like this
{{- range .Values.authorizationPolicies -}}
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: {{ .name }}-authorization-policy
...
{{- end -}}
When I don't set anything from my values.yaml I see the error below
Error: INSTALLATION FAILED: template: microservice/templates/authorization-policies.yaml:5:11: executing "microservice/templates/authorization-policies.yaml" at <.name>: can't evaluate field name in type interface {}
helm.go:84: [debug] template: microservice/templates/authorization-policies.yaml:5:11: executing "microservice/templates/authorization-policies.yaml" at <.name>: can't evaluate field name in type interface {}
INSTALLATION FAILED
main.newInstallCmd.func2
helm.sh/helm/v3/cmd/helm/install.go:154
github.com/spf13/cobra.(*Command).execute
github.com/spf13/cobra@v1.7.0/command.go:940
github.com/spf13/cobra.(*Command).ExecuteC
github.com/spf13/cobra@v1.7.0/command.go:1068
github.com/spf13/cobra.(*Command).Execute
github.com/spf13/cobra@v1.7.0/command.go:992
main.main
helm.sh/helm/v3/cmd/helm/helm.go:83
runtime.main
runtime/proc.go:267
runtime.goexit
runtime/asm_arm64.s:1197
However, if I define authorizationPolicies: []
, then the range doesn't iterate.
Seems to me that Helm does not distinguish between a non-existent value and an empty list or map. If the value is not specified in the values file, Helm treats it as an empty map.
Is there any workaround for this?
The easiest answer is to include the definition of authorizationPolicies: []
as an empty list in your chart's values.yaml
file. Someone installing the chart can still provide a different value using a helm install -f
alternate values file.
The second-easiest answer is to provide a default empty list when setting up the range
loop
{{ range .Values.authorizationPolicies | default list }}
...
{{ end }}
If the value isn't defined anywhere, then .Values.authorizationPolicies
has a special value of nil
. This is different from an empty list or an empty map; it's considered "false" for purposes of conditionals or the default
function. In the underlying Go implementation, the best Go type the template engine has to work with is the "anything" type interface{}
and that's why you see it in the error message.