kubernetes-helm

Override values when including template


I am using helm to generate some yaml files with the following setup:

Values.yaml

---
namespace: ns-one

template.tpl

{{- define "nested.template" -}}
namespace: {{ .Values.namespace }}
{{- end -}}

{{- define "toplevel.template" -}}
  {{- include "nested.template" . -}}
{{- end -}}

include.yaml:

{{- include "toplevel.template" . }}

This works well.

What I would like to do is include another yaml file in which I include "toplevel.template" but override the namespace value. Something like this:

override.yaml:

{{- include "toplevel.template" (dict "ns-two" $.Values.namespace) -}}

So the output would be: namespace: ns-two

Is anyone able to suggest how to do this?


Solution

  • On some level the top-level Helm object is "just" an object, and the parameter you pass to include or template can be any arbitrary value.

    One option is to change the included template to directly take the namespace name. This is mechanically much simpler, but it involves changing the caller, and if the point of the function is to extract values from well-defined places in .Values then you've lost that.

    {{- define "nested.template" -}}
    namespace: {{ . }}
    {{- end -}}
    
    true:
    {{ include "nested.template" .Values.namespace | indent 2 }}
    overridden:
    {{ include "nested.template" "ns-two" | indent 2 }}
    

    The harder approach is to create an object that looks just like the top-level Helm object, but it has the override values you want. You need to create a copy of .Values, set the field you want, and then create a map with a Values field. This works with the unmodified function, and if you copy all of .Values then you can pluck out other settings as you need them.

    {{- $newValues := deepCopy .Values }}
    {{- $_ := set $newValues "namespace" "ns-two" }}
    {{- $newTop := dict "Values" $newValues }}
    {{- include "nested.template" $newTop }}
    

    You could directly copy things like .Files into the object if they were needed, or create a mock .Release where you override .Release.Namespace the same way.