Using the Helm Tpl Function to Refer Values in Values Files

I write Helm charts for my clients to help them deploy applications to Kubernetes easier. Often, they ask me if they can reference values in their values.yaml file to avoid duplicate strings. For example, instead of doing something like this:

image: myregistry.io/dev/myImage:1.0
env:
  - name: ENVIRONMENT
    value: dev

They’d rather do something like this to help organize their values better:

environment: dev
image: myregistry.io/{{ .Values.environment }}/myImage:1.0
env:
  - name: ENVIRONMENT
    value: “{{ .Values.environment }}”

The truth is that your users can reference values in their values file as shown above, but it requires you as the chart developer to write your charts to support this. You can do this by using the tpl function in your Helm chart templates.

The Tpl Function

To quote the Helm documentation, “The tpl function allows developers to evaluate strings as templates inside a template.” Imagine a Deployment resource template contains the following snippet:

    spec:
      containers:
        - name: main
          image: {{ .Values.image }}
          env:
            {{- toYaml .Values.env | nindent 12 }}

This snippet would not allow your users to reference other values in their values file. If they tried, the result of “helm install” or “helm template” would look like this:

    spec:
      containers:
        - name: main
          image: myregistry.io/{{ .Values.environment }}/myImage:1.0
          env:
            - name: ENVIRONMENT
              value: '{{ .Values.environment }}'

As you can see, the template engine rendered the literal value {{ .Values.environment }} instead of the actual setting of that value.

Luckily, fixing this is easy with the tpl function. Here’s a rewritten version of the Deployment snippet using the tpl function:

    spec:
      containers:
        - name: main
          image: {{ tpl .Values.image . }}
          env:
            {{- tpl (toYaml .Values.env) . | nindent 12 }}

Now, when you run “helm install”, the template engine will be able to replace {{ .Values.environment }} with the setting from your values file:

    spec:
      containers:
        - name: main
          image: myregistry.io/dev/myImage:1.0
          env:
            - name: ENVIRONMENT
              value: 'dev'

The tpl function uses a similar syntax as the include function, which I discuss in my post about Named Templates. The first argument is the string you want to render as a template, and the second argument is the scope, which will usually be . (dot), unless you are executing tpl inside a loop, in which case you will want to use $ instead.

On the values.yaml side, your users should remember to wrap values in quotes if the string starts with {{. Otherwise, the template engine will throw an error.

Tpl Security Considerations

Keep in mind that tpl is used to render any user input as a template, and can be used for use cases other than simply referencing other Helm values. Consider your user provides the following values file:

environment: dev
image: myregistry.io/{{ .Values.environment }}/myImage:1.0
env:
  - name: PODS
    value: '{{ lookup "v1" "Pod" "" "" }}'

Is this a malicious input? Maybe, maybe not. Regardless, this input would display all pods in your cluster if the user had permission to do so. Always use proper RBAC in your cluster to prevent users from reading or writing resources they shouldn’t be allowed to.

Thanks For Reading

In this post, you learned how to use the tpl function to allow users to reference values in values files. Are there other Helm topics or tricks you want me to cover? Feel free to leave a comment below!

Austin Dewey

Austin Dewey is a DevOps engineer focused on delivering a streamlined developer experience on cloud and container technologies. Austin started his career with Red Hat’s consulting organization, where he helped drive success at many different Fortune 500 companies by automating deployments on Red Hat’s Kubernetes-based PaaS, OpenShift Container Platform. Currently, Austin works at fintech startup Prime Trust, building automation to scale financial infrastructure and support developers on Kubernetes and AWS. Austin is the author of "Learn Helm", a book focused on packaging and delivering applications to Kubernetes, and he enjoys writing about open source technologies at his blog in his free time, austindewey.com.

1 Comment

Leave a Reply