sps

25 – 27 November 2025

Nürnberg Messe

SPS – Smart Production Solutions 2025

Let's meet!
AppRecode Founder
HomeBlogHelm: How to Reference Variables From values?
HelmTechnologies

Helm: How to Reference Variables From values?

Audio article by AppRecode

0:00/7:49

Summarize with:

ChatGPT iconclaude iconperplexity icongrok icongemini icon
8 mins
01.01.2025
Volodymyr Shynkar CEO and Co-Founder of AppRecode

Volodymyr Shynkar

CEO/CTO

Helm is a package manager for Kubernetes that helps you manage and deploy complex applications. In Helm, variables are used to store values that can be used throughout your chart. These values can be customized for each deployment, allowing you to deploy your application in different environments with different configurations.

Background

Helm is a package manager for Kubernetes that helps you manage and deploy complex applications.

In Helm, variables are used to store values that can be used throughout your chart. These values can be customized for each deployment, allowing you to deploy your application in different environments with different configurations.

Helm provides a straightforward template language that makes it simple to refer to configuration settings that are defined in a “values file.”

e.g. The “name” config value from the “values file” is referred to in the Helm chart template above. The template will eventually be produced like follows, assuming the string “world” is the value of the configuration field “name”:

Referencing a “value” in a Helm chart template appears tidy and easy. So how might we use the Helm chart’s “values file” to refer to other values?

Why?

An example “values file” that provides a collection of API endpoint URLs is shown below:

apiOneUrl: http://example.com/apiOne/v0

 

apiTwoUrl: http://example.com/apiTwo/v3

 

apiThreeUrl: http://example.com/apiThree/v7

You could see that the string “http://example.com/” appears in every configuration field. If we could provide the “values file” like follows, that would be nice:

baseUrl: http://example.com

 

apiOneUrl: “{{ .Values.baseUrl }}/apiOne/v0”

 

apiTwoUrl: “{{ .Values.baseUrl }}/apiTwo/v3”

 

apiThreeUrl: “{{ .Values.baseUrl }}/apiThree/v7”

That will not only eliminate duplication and save a ton of typing, but it will also make updating configuration variables much simpler in the future.

However, since Helm’s template engine won’t parse the “values file,” referencing “.Values.apiOneUrl” in your template will simply return the original string “{{ .Values.baseUrl }}/apiOne/v0”

tpl Function to Rescue

Here is where the Helm chart tpl function comes in in. It enables developers to evaluate texts as templates inside of templates. The function anticipates two inputs:

  • A template string that has to be processed is the first argument.
  • The context data to be used when processing the template string is the final argument. We frequently succeed. This is up-to-date context information to ensure that all configuration settings are accessible throughout template processing.

In your template, you may attempt the following:

MyApiOneUrl: {{ tpl .Values.apiOneUrl . }}

you will find .Values.apiOneUrl ‘s value “{{ .Values.baseUrl }}/apiOne/v0” will be converted into “http://example.com//apiOne/v0” and the above template will be rendered as:

MyApiOneUrl: http://example.com/apiOne/v0

Problem with Non-string Types

When using basic string type configuration settings, the technique works effectively. What happens, though, if the configuration value is of a non-string type, such as a “map” or “list”?

Have a look at the values file below:

baseUrl: http://example.com

apiUrls:

apiOneUrl: “{{ .Values.baseUrl }}/apiOne/v0”

apiTwoUrl: “{{ .Values.baseUrl }}/apiTwo/v3”

apiThreeUrl: “{{ .Values.baseUrl }}/apiThree/v7”

In your template, you may attempt the following:

MyApiUrls: {{ tpl .Values.apiUrls . }}

The following template error will appear:

wrong type for value; expected string; got map[string]interface {}

The error message makes sense because the tpl function anticipates a template string as the first parameter. So how might we address the problem and make our solution applicable to this typical use case?

One option is to feed the non-string type value (in this example, map) to the toYaml function first and then convert it to a “YAML” string:

MyApiUrls:

{{ tpl (.Values.apiUrls | toYaml) . | indent 2 }}

If you use the aforementioned template, it will be appropriately displayed as:

MyApiUrls:

apiOneUrl: http://example.com/apiOne/v0

apiTwoUrl: http://example.com/apiTwo/v3

apiThreeUrl: http://example.com/apiThree/v7

The Complete Solution

We may construct a “named template” to recognize the configuration value type and use the appropriate logic, making the solution portable:

{{ define “render-value” }}

{{- if kindIs “string” .value }}

{{- tpl .value .context }}

{{- else }}

{{- tpl (.value | toYaml) .context }}

{{- end }}

{{- end }}

You may use the include function to call the “named template” in a template:

MyApiOneUrl: {{ include “render-value” ( dict “value” .Values.apiOneUrl “context” .) }}

MyApiUrls:

{{ include “render-value” ( dict “value” .Values.apiUrls “context” .) | indent 2}}

The following will be created from the aforementioned template:

MyApiOneUrl: http://example.com/apiOne/v0

MyApiUrls:

apiOneUrl: http://example.com/apiOne/v0

apiTwoUrl: http://example.com/apiTwo/v3

apiThreeUrl: http://example.com/apiThree/v7

You may also utilize Bitnami’s “common” library chart if you want to avoid having to define your own “named template”. Just add the upcoming dependency to your Chart.yaml to start using it :

dependencies:

– name: common

version: 1.11.1

repository: https://charts.bitnami.com/bitnami

Then, using the same reasoning as the following, you may call the built-in “named template”

MyApiOneUrl: {{ include “common.tplvalues.render” ( dict “value” .Values.apiOneUrl “context” .) }}

Best Practices

Now, let’s explore some best practices that will help you get the maximum out of using the Helm Chart. These are largely based on our experience with managing such charts, defining Helm variables, and other services, such as DevOps maintenance support services

1. When something must be dynamic, chuck it into tpl

Sometimes you get a value that needs to expand at runtime. Then the move is:

{{ tpl .Values.image.full . }}

 

But don’t overuse this or you’ll regret it later—the debugging is… unpleasant.

2. Break big things into small pieces

Composing a URL, an image name, whatever—don’t try to Frankenstein it inside values.yaml.

Let the templates put the puzzle pieces together. Helm is happier that way, and so are future you and your teammates.

3. If you repeat something more than twice, helpers exist for a reason

_helpers.tpl is where repeated logic should live. No need to copy/paste a 4-line snippet in every template. That always backfires in six months.

4. YAML anchors are boring but reliable

YAML anchors don’t “compute” anything. They just clone chunks of YAML. Such an approach is useful when you’re tired of writing the same block three times.

decoration

Unsure whether Helm chart values reference other values or need help with cleaning your YAML file?

As a team with exceptional expertise in Helm charts and container orchestration consulting, we are ready to help you!

Let's talk!

Troubleshooting: Common Mistakes and Simple Fixes

Here are some more tips that will help you avoid common mistakes with the Helm chart.

“Why does Helm ignore my template in values.yaml?”

Because it always does. Move the logic into a template and call tpl if absolutely needed.

“Wrong type for value; expected string; got map”

Happens when you send a map into tpl. It only digests strings.

Subcharts can’t see each other’s values

They’re isolated. Use global.* if they must share something.

YAML anchors don’t magically build dynamic things

They’re copy/paste, nothing else. Good for repetition only.

Overusing tpl

Makes debugging harder than it has to be. Use it sparingly, not by default.

Our Expertise with the Helm Chart

We’ve dealt with Helm charts that started as neat little projects and somehow turned into 800-line YAML creatures with duplicated values, tangled subcharts, and “temporary” fixes from two years ago. While we cannot make Helm values reference other values directly, we can help you with many templates that provide the functionality you need.

Whether you need help with structuring your Helm chart, making Helm reference values in values with templates you need, or help with configuring CI/CD pipelines, our team will be there.

And if you need structure, migration advice, or someone to introduce sanity into CI/CD,  our team’s been there. We have strong expertise in DeOps development services and Kubernetes consulting that will help you configure a solution tailored to your needs. Our specialists will provide you with reliable help in managing Helm values variables.

We will also ensure that your Helm defines variable patterns correctly, ensuring your charts stay flexible, maintainable, and ready for any environment.

To know more about our expertise, make sure to check out our Clutch profile. 

 

Expert Quote:

“Most Helm problems don’t come from Helm at all. They come from trying to make Helm behave like something it’s not. Keep it simple, don’t expect Helm values file reference other values directly, and suddenly everything works again.”

Volodymyr Shynkar, Founder at AppRecode

LinkedIn

Summary

We can combine configuration data into Helm template variables thanks to the solution’s straightforward yet effective template engine. But, occasionally, we could also wish to use Helm’s “values file” as a configuration file. The “named template” implementation of a tpl function-based solution is introduced in this article.

If you are unfamiliar with Helm’s “named template” function, you may want to read Helm official to learn more about what it can accomplish.

In Apprecode, we are always ready to consult you about implementing the DevOps methodology. Please contact us for more information.

FAQ

Can I reference one value from another in values.yaml?

Nope. Helm ignores template syntax in values.

Why doesn’t Helm allow templating there?

To avoid weird circular logic and unpredictable charts.

How do I reuse values across subcharts?

Place them under global.*.

How do I correctly use tpl?

Give it a string that contains template syntax:

{{ tpl .Values.dynamicField . }}

Why does Helm complain about wrong types with tpl?

You passed something that wasn’t a string.

Can I reference local variables in a subchart?

Inside templates, you can reference Helm chart variables. In values.yaml, no.

Are YAML anchors a decent workaround?

For duplication, yes. For templating logic, not at all.

How do I clean up charts with repeated URLs or prefixes?

Move the logic into helpers in _helpers.tpl.

What are tpl’s limitations in Helm 3?

No deep evaluation, confusing errors, and harder debugging.

Is there a helper library to render values the “clean way”?

Many teams use Bitnami’s common.tplvalues.render as a pattern.

Did you like the article?

50 ratings, average 4.8 out of 5

Comments

Loading...

Blog

OUR SERVICES

REQUEST A SERVICE

651 N Broad St, STE 205, Middletown, Delaware, 19709
Ukraine, Lviv, Studynskoho 14

Get in touch

Contact us today to find out how DevOps consulting and development services can improve your business tomorrow.

AppRecode Ai Assistant