'How best to say a value is required in a helm chart?

I am doing this now:

value: {{ required "A valid .Values.foo entry required!" .Values.foo }}

But to give this same message for all required values in the templates is cumbersome and clutters the templates in my opinion.

Is there a better way where we could define it outside the template \ or a cleaner way to do it within the template itself?



Solution 1:[1]

You could do something by taking advantage of range and the fact that null will fail the required check. So in your values.yaml you could have this section for required env vars:

reqEnv:
 - name: "VAR1"
   value: null
 - name: "VAR2"
   value: null

And in the env section of the Deployment you then have:

{{- range .Values.reqEnv }}
          {{ .name }}: {{ required "A value must be entered for all reqEnv entries" .value }}
{{- end }}

Then the user gets an error unless they set all required values of the reqEnv section in their values file or as paramters. Unfortunately what you lose by doing this is the detail of which var is missing. This could be why the official helm charts seem to prefer using required in the way that you already are.

Solution 2:[2]

You can use helm lint with --strict flag to check undefined values

$ helm lint --strict . 
==> Linting .
[INFO] Chart.yaml: icon is recommended
[ERROR] templates/: render error in "mychart/templates/service.yaml": template: mychart/templates/service.yaml:10:19: executing "mychart/templates/service.yaml" at <.Values.foo>: map has no entry for key "foo"

Error: 1 chart(s) linted, 1 chart(s) failed

Solution 3:[3]

To expose name of missing item to required text you can do something like this:

{{- range $field, $my_key := $data }}
 {{- if hasKey $dic1 $my_key }}
  {{ $field }}: {{ index $dic1 $my_key | b64enc}}
 {{- else if hasKey $dic2 $my_key }}
  {{ $field }}: {{ index $dic2 $my_key | b64enc}}
 {{- else }}
  {{ $field }}: {{ required (printf "key %s is missing" $my_key) nil }}
 {{- end }}
{{- end }}

Solution 4:[4]

I've come up with an alternative hack trying to solve this problem. It's questionable whether this is actually any better that the built in solution, but I thought it might be worth noting down here as an option.

Add a function to your _helpers.tpl (or wherever):

{{/*
Require and include a value
*/}}
{{- define "require" -}}
    {{- $scope := index . 0 -}}
    {{- $name := index . 1 -}}
    {{required (print "Missing required value: " $name) (index $scope "Values" $name)}}
{{- end}}

Then in your template call it with:

value: {{ include "require" (list . "foo") }}

If a value is missing, it errors with message:

Missing required value: foo

Otherwise, it inserts the value.


Edit: To make this work for nested values, you need a slightly more complex helper:

{{/*
Index a nested component
*/}}
{{- define "indexNested" -}}
    {{- $message := index . 0 -}}
    {{- $object := index . 1 -}}
    {{- $path := (mustRegexSplit "\\." (index . 2) -1) -}}
    {{- range $path -}}
        {{- if not $object -}}
            {{ fail $message }}
        {{- end -}}
        {{- $object = index $object . -}}
    {{- end -}}
    {{ required $message $object }}
{{- end}}

{{/*
Require and include a value
*/}}
{{- define "require" -}}
    {{- $scope := index . 0 -}}
    {{- $name := index . 1 -}}
    {{ include "indexNested" (list (print "Missing required value: " $name) $scope.Values $name) }}
{{- end}}

Now you can access the foo.bar value with:

{{ include "require" (list . "foo.bar") }}

Solution 5:[5]

Define the required values on top of your manifest as variables utilizing the required function.

deployment.yaml

{{- $name := .Values.name | required ".Values.name is required." -}}

apiVersion: apps/v1
kind: Deployment
metadata: 
  name: {{ $name }}
 ....

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ryan Dawson
Solution 2 edbighead
Solution 3 Essential15
Solution 4
Solution 5 pijemcolu