Search code examples
kubernetes-helmhelm3

Helm when variable child key does not exist fallback to default next variable


Using Helm v3 the following template is breaking with error:

Error: INSTALLATION FAILED: template: rabbitmq/templates/secrets.yaml:4:31: executing "rabbitmq/templates/secrets.yaml" at <.Values.global.rabbitmq.password>: nil pointer evaluating interface {}.rabbitmq

Contents of rabbitmq/templates/secrets.yaml:

{{- $def := index .Values "default" -}}
apiVersion: v1
data:
  rabbitmq-password: {{ $def.global.rabbitmq.password | default $def.RABBITMQ_PASSWORD | b64enc | quote }}
  rabbitmq-erlang-cookie: {{ randAlphaNum 20 | b64enc | quote }}
kind: Secret
metadata:
  name: rabbitmq-password
type: Opaque

This works when .Values.global.{} exists. However when .Values.global does not exist it does not fallback to $def.RABBITMQ_PASSWORD as I would expect.


Solution

  • In your code, the variable $def is always .Values.default (that is, whatever's under the top-level key default: in the values.yaml file). That's probably not what you want.

    The pattern I've found successful here is to set a variable for each level of the hierarchy, defaulting it to an empty dictionary if it doesn't exist. That will let you do recursive lookups.

    I'm guessing, when you say $def.global, you really mean the top-level .Values.global object, which has special meaning in a Helm subchart context. So you could do these lookups safely like:

    {{- $def := .Values.default | default dict }}
    {{- $global := .Values.global | default dict }}
    {{- $rabbitmq := $global.rabbitmq | default dict }}
    rabbitmq-password: {{ $rabbitmq.password | default $def.RABBITMQ_PASSWORD | b64enc | quote }}