Helm
Template Helpers
Kubernetes
Filtered List
DevOps

Creating a filtered list using helm template helpers

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Helm templates do not have a rich query language for lists, so filtering usually means ranging over items and deciding which ones to keep. Template helpers become useful when that filtering logic needs to be reused in more than one manifest.

The key idea is that helpers in _helpers.tpl return rendered text. If you want to treat the result like a list again, you usually render YAML in the helper and parse it back with a YAML function in the caller.

Start with a simple values list

Suppose your chart receives a list of services and only some are enabled:

yaml
1services:
2  - name: api
3    port: 8080
4    enabled: true
5  - name: admin
6    port: 8081
7    enabled: false
8  - name: worker
9    port: 8082
10    enabled: true

If you only need the filtered list in one place, a plain range plus if is enough:

gotemplate
1{{- range .Values.services }}
2{{- if .enabled }}
3- name: {{ .name }}
4  containerPort: {{ .port }}
5{{- end }}
6{{- end }}

That is often the clearest answer. Reach for a helper only when the same filtering rule will be reused.

Build a reusable helper that returns YAML

In _helpers.tpl, you can collect the enabled items into a list and emit YAML:

gotemplate
1{{- define "mychart.enabledServices" -}}
2{{- $result := list -}}
3{{- range .Values.services -}}
4  {{- if .enabled -}}
5    {{- $result = append $result . -}}
6  {{- end -}}
7{{- end -}}
8{{- toYaml $result -}}
9{{- end -}}

Then in a manifest, convert the helper output back into a structured value:

gotemplate
1{{- $enabledServices := include "mychart.enabledServices" . | fromYamlArray -}}
2ports:
3{{- range $enabledServices }}
4  - name: {{ .name }}
5    containerPort: {{ .port }}
6{{- end }}

This pattern keeps the filtering logic in one place while still allowing the caller to loop over the filtered items as real objects.

Use helpers when the same rule appears in multiple manifests

Helpers are most useful when the same filtered set feeds several resources. For example, you might use the same enabled services list in:

  • a Deployment container port section
  • a Service manifest
  • a ConfigMap with generated metadata

Without a helper, each template repeats the same range and if logic. With a helper, you centralize the rule once.

Another benefit is consistency. If the definition of "enabled" changes later, you update the helper instead of hunting through several manifests.

Keep the filtering rule easy to understand

Helm templates become hard to maintain quickly if you push too much application logic into them. Prefer small helpers with obvious intent.

For example, filtering by one boolean is straightforward:

gotemplate
{{- if and .enabled (ne .name "admin") -}}

Filtering by three nested conditions, cross-referenced labels, and default fallbacks is usually a signal that the values should be reshaped before they reach the chart.

A good rule is that templates should mostly format configuration, not implement business logic.

Test the rendered result early

Because helpers return text, whitespace and indentation mistakes are easy to miss. Use helm template to inspect the final output while developing:

bash
helm template mychart ./mychart

If you are parsing helper output back into a list with fromYamlArray, this command is especially useful because YAML formatting errors in the helper can break later rendering in ways that are not immediately obvious.

Common Pitfalls

The most common mistake is forgetting that include returns a string, not a native Helm list. If you want structured data again, you need to serialize and parse it intentionally.

Another issue is overusing helpers for one-off filters. If the logic is needed only once, a simple range with an if is easier to read than a round trip through _helpers.tpl.

Whitespace bugs are also common. Aggressive use of trimming markers can accidentally remove needed newlines or indentation, producing invalid YAML.

Finally, do not turn Helm templates into a data-processing language. When filtering rules become complex, it is usually better to simplify the values shape or preprocess the data upstream.

Summary

  • In Helm, list filtering is usually done with range plus if.
  • Use a helper when the same filtering rule must be reused across templates.
  • Helpers return strings, so structured reuse often means toYaml in the helper and fromYamlArray in the caller.
  • Keep helper logic small and focused so the chart stays maintainable.
  • Validate rendered output with helm template to catch YAML and whitespace issues early.

Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design