Search code examples
go-templateskubernetes-helm

How can you call a helm 'helper' template from a subchart with the correct context?


Helm charts define helper templates in _helpers.tpl which are used to create normalized names for the services. The standard form of the template for a service (DNS) name is:

{{- define "postgresql.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}

If using postgresql as a subchart, how are you supposed to use DNS-based service discovery to refer to it? A common pattern seems to be to copy the subchart helpers into the parent chart.

{{- define "keycloak.postgresql.fullname" -}}
{{- $name := default "postgresql" .Values.postgresql.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}

This is total madness for obvious reasons!!!

Surely there's a better way to use the subchart helper? If you could create a context object then it would be possible to invoke it, something like:

value: {{ template "postgresql.fullname" ({Chart: {Name: 'not-used'}, Release: {Name: .Release.Name}, Values: { nameOverride: .Values.postgresql.nameOverride}}) }}

Sadly I have no idea how to actually create such a context dynamically. This would still break if the helper function changed to reference new properties, but in an obvious way.

Alternatively, a different way to make available the service name from a subchart?


Solution

  • As of https://github.com/helm/helm/pull/9957 (merged August 31, 2021 and released in Helm 3.7), you can invoke the subchart's named template in the context of that subchart by using .Subcharts.[chartName] as the second argument.

    For example, assuming your keycloak subchart names it service like {{ template "keycloak.fullname" . }}-http you could refer to that service's name from a parent chart as follows:

    {{ template "keycloak.fullname" .Subcharts.keycloak }}-http