How to conditionally render helm templates based on existence of nested values

10/21/2020

I have a template that renders a secret containing the credentials to log in to my server. There is a deployment configuration in which this is done insecurely, in which case I don't want to render the secret. Normally my values.yaml contains auth.myapp.username, and auth.myapp.password, however when the deployment lacks credentials, the whole auth section no longer exists.

My secret template looks like this:

{{ if .Values.auth.myapp.username }}
apiVersion: v1
kind: Secret
metadata:
  name: myapp-credentials-secret
type: Opaque
data:
  USERNAME: {{ .Values.auth.myapp.username | b64enc }}
  PASSWORD: {{ .Values.auth.myapp.password | b64enc }}
{{ end }}

However I get an error when running helm install on this because the 'auth' value doesn't exist, it fails to lookup myapp from it.

I know I can get around this by not using the --strict flag, but I don't have control over that, is there a proper way of predicating on nested values?

-- Andy
kubernetes
kubernetes-helm

2 Answers

10/23/2020

You can use the standard default function to fill in layers of the hierarchy that don't exist, combined with the Sprig dict function to create an empty dictionary:

{{- $auth := .Values.auth | default dict -}}
{{/* $auth is the "auth" object from the top-level values, or an empty
     dictionary if there was no such value */}}

That will let you step through this structure one level at a time:

{{- $auth := .Values.auth | default dict -}}
{{- $myapp := $auth.myapp | default dict -}}
{{- if and $myapp.username $myapp.password -}}
apiVersion: v1
kind: Secret
...
data:
  USERNAME: {{ $myapp.username | b64enc }}
  PASSWORD: {{ $myapp.password | b64enc }}
{{ end }}
-- David Maze
Source: StackOverflow

10/21/2020

Use haskey function:

{{ if haskey .Values "auth" }}
apiVersion: v1
kind: Secret
metadata:
  name: myapp-credentials-secret
type: Opaque
data:
  USERNAME: {{ .Values.auth.myapp.username | b64enc }}
  PASSWORD: {{ .Values.auth.myapp.password | b64enc }}
{{ end }}

The hasKey function returns true if the given dict contains the given key.

hasKey $myDict "name1"

If the key is not found, this returns false.

-- Oliver
Source: StackOverflow