Skip to main content

Implementing Template Flow Control

1. Using Conditional Statements

Statement Description Example
has Checks if a key exists in a map or list {{- if has "key" .Values.configMap }}<br> Key exists<br>{{- end }}
eq Checks equality between two values {{- if eq .Values.env "production" }}<br> Production config<br>{{- end }}
ne Checks inequality between two values {{- if ne .Values.env "development" }}<br> Not development<br>{{- end }}
lt, le, gt, ge Comparison operators for numbers {{- if lt .Values.replicaCount 3 }}<br> Less than 3 replicas<br>{{- end }}
and Logical AND operator {{- if and (eq .Values.env "prod") (gt .Values.replicaCount 2) }}<br> Prod with more than 2 replicas<br>{{- end }}
or Logical OR operator {{- if or (eq .Values.env "dev") (eq .Values.env "staging") }}<br> Dev or staging<br>{{- end }}
not Logical NOT operator {{- if not (eq .Values.env "production") }}<br> Not production<br>{{- end }}

Example: Conditional ConfigMap Creation

apiVersion: v1<br>kind: ConfigMap<br>metadata:<br>  name: {{ include "myapp.fullname" . }}<br>{{- if .Values.configMap.enabled }}<br>data:<br>  config.yaml: |<br>    logLevel: {{ .Values.configMap.logLevel }}<br>{{- end }}

Example: Environment-Based Deployment

apiVersion: apps/v1<br>kind: Deployment<br>metadata:<br>  name: {{ include "myapp.fullname" . }}<br>spec:<br>  replicas: {{- if eq .Values.env "production" }}<br>    5<br>  {{- else }}<br>    1<br>  {{- end }}
Note: Conditional statements in Helm templates are evaluated during the template rendering phase, not at runtime.

2. Implementing Loops

Directive Description Usage
.Values.loopItems List of items to iterate over loopItems: [ "item1", "item2" ]
.Values.loopItem Current item in loop name: {{ .Values.loopItem }}

Example: Looping Over Items

loopItems:
  - "app1"
  - "app2"

{{- range .Values.loopItems }}
name: {{ . }}
{{- end }}

Example: Looping with Index

{{- range $index, $item := .Values.loopItems }}
{{ $index }}: {{ $item }}
{{- end }}

3. Using with Scope

Property Description Values
.Values Values passed to the chart from the user {}
.Release Information about the release {name, namespace, revision, status}
.Chart Metadata about the chart {name, version, appVersion}
.Files Access to files in the chart {}
.Capabilities Kubernetes version and features supported {kubernetesVersion, apiVersions}
.Template Information about the current template {name, basepath}

Example: Accessing Release Info

{{ .Release.Name }}-{{ .Release.Revision }}

Example: Using Chart Metadata

Chart: {{ .Chart.Name }} v{{ .Chart.Version }}
Note: The scope is automatically provided by Helm during template rendering and does not need to be explicitly passed.

4. Defining Variables

Variable Type Description Usage Example Notes
.Values Root values passed to the chart {{ .Values.database.host }} Accessed via dot notation
.Release Release-specific information {{ .Release.Name }} Includes name, namespace, and revision
.Chart Chart metadata {{ .Chart.Name }} Provides chart name and version
.Files Access to chart files {{ .Files.Get "config.yaml" }} Allows reading of files within the chart
.Capabilities Kubernetes version and features {{ .Capabilities.KubeVersion }} Used for feature detection

Example: Setting and Using Variables in Values

# values.yaml
database:
  host: "db.example.com"
  port: 5432
  username: "admin"

ingress:
  enabled: true
  hosts:
    - host: "app.example.com"
      paths:
        - path: /
          pathType: Prefix

Example: Using Variables in Templates

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "myapp.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "myapp.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          ports:
            - name: http
              containerPort: {{ .Values.service.port }}
              protocol: TCP
Note: Variables defined in values.yaml can be overridden at release time using helm install --set key=value or by providing a custom values file.

5. Checking Value Existence

Check Type Description Example
hasKey Checks if a key exists in a map or object
{{- if (hasKey .Values "database") -}}
Database config is present
{{- end -}}
eq Checks if two values are equal
{{- if (eq .Values.service.type "LoadBalancer") -}}
Using LoadBalancer
{{- end -}}
ne Checks if two values are not equal
{{- if (ne .Values.replicaCount 1) -}}
Replicas are not 1
{{- end -}}
gt Checks if value is greater than another
{{- if (gt .Values.replicaCount 3) -}}
More than 3 replicas
{{- end -}}
lt Checks if value is less than another
{{- if (lt .Values.memoryLimit "512Mi") -}}
Memory limit is less than 512Mi
{{- end -}}
and Checks if all conditions are true
{{- if (and (hasKey .Values "database") (eq .Values.database.enabled true)) -}}
Database is enabled
{{- end -}}
or Checks if any condition is true
{{- if (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) -}}
Service is either NodePort or LoadBalancer
{{- end -}}

Example: Checking for a specific key in values

{{- if (hasKey .Values "ingress") }}
ingress:
  enabled: {{ .Values.ingress.enabled }}
{{- end }}

Example: Using multiple conditions to check existence and value

{{- if (and (hasKey .Values "database") (eq .Values.database.enabled true)) }}
Database is enabled in values
{{- end }}
Note: The hasKey function is particularly useful when checking for optional configuration sections in Helm charts.

6. Using Boolean Logic

Operator Description Example Notes
eq Equal to {{ eq .Values.image.tag "v1.0" }} Compares two values for equality
ne Not equal to {{ ne .Values.image.tag "v1.0" }} Checks if two values are not equal
and Logical AND {{ and (eq .Values.image.tag "v1.0") (gt .Values.replicaCount 1) }} Returns true if all values are truthy
or Logical OR {{ or (eq .Values.image.tag "v1.0") (eq .Values.image.tag "v2.0") }} Returns true if any value is truthy
not Logical NOT {{ not (eq .Values.image.tag "v1.0") }} Negates a boolean value
gt Greater than {{ gt .Values.replicaCount 3 }} Compares two numbers
lt Less than {{ lt .Values.replicaCount 5 }} Compares two numbers
ge Greater than or equal to {{ ge .Values.replicaCount 3 }} Compares two numbers
le Less than or equal to {{ le .Values.replicaCount 5 }} Compares two numbers
has Checks if a key exists in a map {{ has "image" .Values }} Useful for conditional rendering

Example: Conditional rendering with boolean logic

{{- if (eq .Values.image.tag "v1.0") }}
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
{{- else if (eq .Values.image.tag "v2.0") }}
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
{{- else }}
image: {{ .Values.image.repository }}:latest
{{- end }}

Example: Combining conditions with and and or

{{- if (and (eq .Values.env "prod") (ge .Values.replicaCount 3)) }}
replicas: {{ .Values.replicaCount }}
{{- else if (or (eq .Values.env "staging") (eq .Values.env "dev")) }}
replicas: 1
{{- end }}
Note: Boolean logic in Helm templates is evaluated at template rendering time, not during chart installation.

7. Comparing Values

Operator Description Example Notes
eq Equal to {{ eq .Values.key1 .Values.key2 }} Compares two values for equality
ne Not equal to {{ ne .Values.key1 .Values.key2 }} Compares two values for inequality
lt Less than {{ lt .Values.number1 .Values.number2 }} Compares numeric values
le Less than or equal to {{ le .Values.number1 .Values.number2 }} Compares numeric values
gt Greater than {{ gt .Values.number1 .Values.number2 }} Compares numeric values
ge Greater than or equal to {{ ge .Values.number1 .Values.number2 }} Compares numeric values
and Logical AND {{ and (eq .Values.key1 "value") (ne .Values.key2 "other") }} Requires all conditions to be true
or Logical OR {{ or (eq .Values.key1 "value") (eq .Values.key2 "other") }} Requires at least one condition to be true
not Logical NOT {{ not (eq .Values.key1 "value") }} Negates a boolean expression

Example: Using eq in a conditional

{{- if (eq .Values.service.type "LoadBalancer") }}
service:
  type: LoadBalancer
  port: {{ .Values.service.port }}
{{- else }}
service:
  type: ClusterIP
  port: {{ .Values.service.port }}
{{- end }}

Example: Using and and or

{{- if (and (eq .Values.env "prod") (gt .Values.replicaCount 3)) }}
replicas: {{ .Values.replicaCount }}
{{- else if (or (eq .Values.env "dev") (eq .Values.env "staging")) }}
replicas: 1
{{- end }}

8. Breaking Loop Iteration

Directive Description Usage
break Exits the loop immediately break;

Example: Breaking Loop Iteration

{{- range $index, $value := .Values.items }}
  {{- if eq $value.name "stop" }}
    {{- break }}
  {{- end }}
  Item: {{ $value.name }}
{{- end }}

9. Handling Empty Values

Property Description Example
emptyVal Value to use when a variable is empty or undefined {{ .Values.emptyVal }}
defaultVal Default value if variable is not set {{ default "defaultValue" .Values.nullVal }}

Example: Using default for empty values

{{- $val := default "default-value" .Values.nullVal -}}
{{ $val }}

Example: Conditional rendering with empty values

{{- if .Values.emptyVal -}}
<div>{{ .Values.emptyVal }}</div>
{{- else -}}
<div>No value provided</div>
{{- end -}}

10. Using Complex Conditionals

Expression Type Syntax Description Notes
.Values.myValue eq .Values.myValue "production" Equality check Can be used in if statements
.Values.env ne .Values.env "staging" Inequality check Checks if values are not equal
.Values.replicaCount gt .Values.replicaCount 3 Greater than Compares numeric values
.Values.memoryLimit lt .Values.memoryLimit "512Mi" Less than Compares numeric or string values
.Values.enabled and .Values.enabled .Values.debug Logical AND Both conditions must be true
.Values.debug or .Values.debug .Values.verbose Logical OR At least one condition must be true
.Values.env not .Values.env Logical NOT Negates a boolean value

Example: Complex Conditional Logic

{{- if and (eq .Values.env "production") (gt .Values.replicaCount 3) }}
replicas: {{ .Values.replicaCount }}
{{- else if or (eq .Values.env "staging") (eq .Values.env "development") }}
replicas: 1
{{- else }}
replicas: 0
{{- end }}

Example: Nested Conditionals with Variables

{{- $isProd := eq .Values.env "production" }}
{{- $hasHighReplicas := gt .Values.replicaCount 5 }}
{{- if and $isProd $hasHighReplicas }}
resources:
  limits:
    cpu: "2"
    memory: "4Gi"
{{- else if $isProd }}
resources:
  limits:
    cpu: "1"
    memory: "2Gi"
{{- end }}
Note: Complex conditionals in Helm templates can become hard to read. Consider extracting logic into helper templates or using include for better maintainability.

11. Implementing Dynamic Resource Creation

Dynamic resource creation in Helm charts allows you to conditionally create Kubernetes resources based on chart values or other runtime conditions. This is particularly useful for creating scalable and flexible deployments.

Property Description Values Notes
.Values.dynamicResources Enables or disables dynamic resource creation true / false Default: false
.Values.resourceTemplates List of resource templates to render dynamically Array of template names Each template must exist in templates/

Example: Conditional Deployment Creation

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "myapp.fullname" . }}-{{ .Values.dynamicResource.name }}
spec:
  replicas: {{ .Values.dynamicResource.replicas }}
  selector:
    matchLabels:
      {{- include "myapp.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- include "myapp.podLabels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"

Example: Using Range to Create Multiple Resources

{{- range .Values.dynamicResources }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "myapp.fullname" $ }}-{{ .name }}
data:
  config.yaml: |
    key: {{ .value }}
{{- end }}
Note: When using dynamic resource creation, ensure that the templates you reference are properly validated to avoid runtime errors during chart installation.

Was this article helpful?