Chart Templates
Helm Chart Templates define reusable Kubernetes configurations for consistent, scalable deployments using templating and dependency management.
Chart Templates are the core components of a Helm chart that define Kubernetes manifest files dynamically using the Go templating language. They enable the generation of Kubernetes resource definitions based on input values and logic, allowing charts to be reusable, parameterized, and adaptable to different deployment environments. Templates are written in YAML format enriched with template syntax, which Helm processes to produce valid Kubernetes manifests when a chart is installed or upgraded.
Structure and Purpose of Chart Templates
Chart Templates reside in the templates/ directory of a Helm chart. Each template file corresponds to one or more Kubernetes resources, such as Deployments, Services, ConfigMaps, Secrets, Ingresses, or custom resource definitions. Templates use placeholders, control structures, and functions provided by Helm and Go templates to generate resource manifests dynamically.
The primary purpose of templates is to:
- Abstract repetitive Kubernetes YAML manifests into configurable templates.
- Inject user-provided or default values into manifests through the
values.yamlfile. - Support conditional logic to include or exclude resources or fields.
- Facilitate reuse and DRY (Don't Repeat Yourself) principles through named templates and partials.
- Enable environment-specific customization without modifying raw Kubernetes manifests.
Template Syntax and Components
Template Directives and Expressions
Templates use double curly braces {{ ... }} to enclose template expressions. These expressions can output values, invoke functions, or control rendering flow. For example:
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-service
spec:
type: {{ .Values.service.type }}
{{ .Release.Name }}accesses the release name.{{ .Values.service.type }}accesses the value defined invalues.yamlunderservice.type.
Pipeline and Functions
Templates support pipelines where the output of one function is passed as input to another, separated by the pipe | operator. Functions perform string manipulation, list operations, arithmetic, and other transformations.
Example:
name: {{ .Release.Name | lower | trunc 10 }}
This converts the release name to lowercase and truncates it to 10 characters.
Flow Control, Variables, and Scope
Conditionals
Templates use if, else if, and else blocks to conditionally render parts of manifests:
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-ingress
spec:
rules:
- host: {{ .Values.ingress.host }}
http:
paths:
- path: /
backend:
service:
name: {{ .Release.Name }}-service
port:
number: 80
{{- end }}
The above snippet only creates an Ingress resource if ingress.enabled is true.
Loops
range iterates over lists or maps:
{{- range $key, $value := .Values.labels }}
{{ $key }}: {{ $value }}
{{- end }}
This can be used to dynamically generate labels or annotations.
Variables
Variables can be defined and assigned within templates to hold intermediate values and improve readability and reuse:
{{- $fullname := printf "%s-%s" .Release.Name .Chart.Name }}
metadata:
name: {{ $fullname }}
Variables scoped within blocks prevent accidental overrides elsewhere.
Named Templates and Reuse
Named templates are reusable snippets defined with the define directive. They improve modularity and avoid duplication. Named templates are invoked using the template directive.
Example:
{{- define "mychart.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
metadata:
labels:
{{- template "mychart.labels" . | nindent 4 }}
This allows a consistent set of labels to be injected wherever needed.
Chart File Access and Values Injection
Templates access values from multiple predefined contexts:
.Values: User-defined values fromvalues.yamlor overrides..Release: Metadata about the current release (name, namespace, time)..Chart: Metadata about the chart itself (name, version)..Files: Access to non-template files bundled with the chart..Capabilities: Kubernetes API version and feature detection..Template: Information about the current template file.
This context system allows templates to be flexible and context-aware.
YAML Generation and Whitespace Control
Helm templates generate YAML output, so controlling indentation and whitespace is critical to produce valid manifests. Helm provides special syntax to trim whitespace:
{{-trims whitespace to the left.-}}trims whitespace to the right.{{- ... -}}trims whitespace on both sides.
Functions like indent and nindent are used to insert indentation for nested YAML blocks:
metadata:
labels:
{{ .Values.labels | toYaml | indent 4 }}
This converts labels map to YAML and indents it properly.
Cluster Lookups in Templates
Templates can perform lookups against the Kubernetes cluster at render time using the lookup function. This enables charts to query existing resources and make decisions accordingly.
Example:
{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace "my-secret" }}
{{- if $existingSecret }}
# Use existing secret
{{- else }}
# Create new secret
{{- end }}
Lookups allow charts to be more intelligent and handle upgrades or coexist with pre-existing resources.
Template Debugging
Helm provides tools and techniques to debug templates:
- The command
helm templaterenders templates locally without installing, allowing inspection of generated manifests. - The
--debugflag withhelm installorhelm upgradegives detailed error messages. - The
requiredfunction can assert mandatory values and fail early. - Using
{{- printf "%#v" . }}or similar debugging prints can output the current context for inspection. - Careful whitespace control prevents YAML parsing errors.
Summary
Chart Templates transform static Kubernetes YAML manifests into dynamic, flexible, and reusable configurations. They leverage Go templating features integrated with Helm-specific objects and functions to manage complex deployments efficiently. Mastery of template syntax, flow control, variable scope, and context usage is essential to create robust Helm charts that adapt to various environments and requirements seamlessly.