if / else Conditionals
Use if, else if, and else to include parts of a manifest only when a condition is true.
{{- if .Values.ingress.enabled }}
...
{{- end }}Templates often need to include a block only under certain conditions — an Ingress only when enabled, resource limits only when set. That is what if is for.
Syntax
{{ if CONDITION }} ... {{ else }} ... {{ end }}What counts as false
A value is treated as false if it is a boolean false, the number 0, an empty string, an empty list or map, or nil. Everything else is true.
Operators
Go templates use function-style comparisons: eq, ne, lt, gt, and the logical and, or, not.
Example
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "mychart.fullname" . }}
{{- else }}
# Ingress disabled; nothing rendered
{{- end }}
replicas: {{ if eq .Values.env "prod" }}5{{ else }}1{{ end }}When to use it
- A chart author wraps the Ingress resource in an if block so it is only rendered when .Values.ingress.enabled is true, preventing unused resources from being created.
- A developer uses if/else to select between ClusterIP and NodePort service manifests based on a values flag, keeping both options in a single chart.
- A platform template conditionally adds a tolerations block when .Values.tolerations is non-empty, avoiding an empty tolerations key that could confuse validation webhooks.
More examples
Conditional Ingress resource
Wraps the entire Ingress manifest in an if block so it is only rendered when the operator explicitly enables ingress.
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "myapp.fullname" . }}
spec:
rules:
- host: {{ .Values.ingress.host | quote }}
{{- end }}if / else if / else pattern
Uses the full if/else if/else chain to add service-type-specific annotations based on the configured service type.
{{- if eq .Values.service.type "LoadBalancer" }}
# LoadBalancer-specific annotation
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: external
{{- else if eq .Values.service.type "NodePort" }}
# NodePort-specific annotation
annotations:
prometheus.io/scrape: "true"
{{- else }}
# ClusterIP - no special annotations
{{- end }}Guard optional value block
Only renders tolerations and nodeSelector blocks when those values are provided, keeping the YAML clean for default deployments.
spec:
template:
spec:
{{- if .Values.tolerations }}
tolerations:
{{- toYaml .Values.tolerations | nindent 8 }}
{{- end }}
{{- if .Values.nodeSelector }}
nodeSelector:
{{- toYaml .Values.nodeSelector | nindent 8 }}
{{- end }}
Discussion