Part 3: Advanced Templates and Values

Series Navigation: ← Part 2: Creating Your First Chart | Back to Series Overview | Part 4: Chart Dependencies and Repositories β†’

Introduction

In Part 2, we built a functional Helm Chart with basic templating. Now it's time to level up. In my experience, the real power of Helm emerges when you master advanced templating techniquesβ€”conditional logic, loops, complex value manipulation, and reusable template functions.

This article covers the templating patterns I use daily when building Charts for complex TypeScript applications. These techniques have saved me countless hours and prevented numerous deployment errors.

Template Functions and Pipelines

Helm uses Go's template language with Sprig functions. Understanding pipelines is crucial for writing clean templates.

Basic Pipelines

Pipelines pass values from left to right:

# Basic usage
{{ .Values.image.repository }}

# With function
{{ .Values.name | upper }}

# Multiple functions (pipelines)
{{ .Values.name | upper | quote }}

# Trim and quote
{{ .Values.description | trim | quote }}

Common Template Functions

Here are functions I use most often:

String Functions:

Default Values:

Type Conversion:

Encoding:

Real-World Example: Dynamic Labels

Here's how I build dynamic labels in my TypeScript app deployments:

Conditional Logic

Conditional logic allows charts to adapt to different scenarios.

If/Else Statements

Basic conditional structure:

With else:

With else if:

Comparison Operators

Practical Example: Environment-Specific Configuration

This is a pattern I use frequently for TypeScript applications:

Loops and Ranges

Loops iterate over lists and maps, essential for dynamic configurations.

Range Over Lists

values.yaml:

Range Over Maps

values.yaml:

Range with Index

Practical Example: Multiple Ingress Hosts

This pattern handles multiple domains for a TypeScript API:

Named Templates and Includes

Named templates (also called partials) make charts maintainable and DRY.

Defining Named Templates

In _helpers.tpl:

Using Named Templates

Template vs Include

  • template: Inserts template without indentation control

  • include: Returns string that can be piped (e.g., for nindent)

Always use include with nindent for proper YAML formatting:

Complex Values Manipulation

Merging Values

Combining multiple value sources:

Working with Lists

Working with Dictionaries

Advanced Practical Examples

Multi-Environment TypeScript API Configuration

values.yaml:

deployment.yaml:

Dynamic Feature Flags

values.yaml:

configmap.yaml:

Dynamic Service Ports

values.yaml:

service.yaml:

Template Variables and Scope

Understanding variable scope prevents common errors.

Local Variables

Variables in Ranges

Inside range loops, . changes context:

Notice $ is used to access root values inside the range.

With Blocks

with changes scope to a specific value:

Template Comments and Formatting

Comments

Whitespace Control

Control whitespace with -:

This is crucial for clean YAML output:

Debugging Templates

Debug Output

Testing Templates

What's Next?

We've covered advanced templating that handles complex scenarios. In Part 4, we'll explore:

  • Managing chart dependencies

  • Working with subcharts

  • Creating and hosting chart repositories

  • Consuming charts from Artifact Hub

  • Chart versioning strategies

  • Library charts for shared templates


Series Navigation: ← Part 2: Creating Your First Chart | Back to Series Overview | Part 4: Chart Dependencies and Repositories β†’

Key Takeaways

  • βœ… Pipelines chain functions for powerful value transformations

  • βœ… Conditional logic enables environment-specific configurations

  • βœ… Range loops handle dynamic lists and maps efficiently

  • βœ… Named templates promote DRY principles and maintainability

  • βœ… Always use include with nindent for proper YAML formatting

  • βœ… Understand variable scope, especially in loops and with blocks

  • βœ… Whitespace control with - produces clean YAML output

  • βœ… Debug templates with helm template and --debug flag

Last updated