How to merge named templates in Helm

Viewed 289

Suppose we have the following in, say, _helpers.tpl:

{{- define "app.selectorLabels" -}}
app.kubernetes.io/name: app
app.kubernetes.io/instance: instance
{{- end }}

{{- define "app.component.selectorLabels" -}}
{{ include "app.selectorLabels" . }}
app.kubernetes.io/component: component
{{- end }}

{{- define "app.labels" -}}
foo: bar
{{ include "app.selectorLabels" . }}
{{- end }}

{{- define "app.component.labels" -}}
{{ include "app.labels" . }}
{{ include "app.component.selectorLabels" . }}
{{- end }}

Now the app.component.labels named template - used , say, with include somewhere in svc.yaml or whatever - will contain the content of app.selectorLabels twice and will render as the following:

foo: bar
app.kubernetes.io/name: app
app.kubernetes.io/instance: instance
app.kubernetes.io/name: app
app.kubernetes.io/instance: instance
app.kubernetes.io/component: component

Is there any way to merge the two includes in app.component.labels definition so that the duplicates will merge?

1 Answers

You cannot merge templates since they output just text, it's not actual structured data for go. But you can do some tricks with dicts.

{{- define "app.component.labels" -}}
{{- $appLabels := fromYaml (include "app.labels" .) -}}
{{- $selectorLabels := fromYaml (include "app.component.selectorLabels" .) -}}
{{- $labels := merge $appLabels $selectorLabels -}}
{{ toYaml $labels }}
{{- end -}}

The key here is fromYaml, toYaml and the merge function. There are a few variations for merge and the order matters, you need to decide which way you want precisely. You can check the docs http://masterminds.github.io/sprig/dicts.html


That said, it may be better to simply not include the selector labels in app labels in order to sidestep the problem altogether.

Related