Flow Control and Conditionals in Helm
In this article, we will see what is Flow Control and Conditionals in Helm.
Helm provides us the ability to control the flow of a template’s generation. We can generate the template based on dynamic conditions. In simple words, Flow Control is just like the conditional statements in any other programming language. Following are the control structures in Helm:
- if/else
- with
- range
In this blog, we’ll talk about if/else control structure with some examples.
if/else
Let’s talk about if/else conditional blocks. Here the condition will be evaluated by the Pipeline to see whether the condition is true or false. The basic structure of if/else block is this:
{{ if VALUE or PIPELINE }}
# Do something
{{ else if OTHER VALUE or OTHER PIPELINE }}
# Do something else
{{ else }}
# Default
Note that we can use only if condition too.
Here are our values.yaml and service.yaml files:
values.yaml-
replicaCount: 1
image:
repository: nginx
tag: 1.21.6
pullPolicy: Always
environment: uat
templates/service.yaml-
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
{{- if .Values.environment }}
labels:
env: {{ .Values.environment }}
{{- end }}
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 9376
The actual service.yaml file will be:
apiVersion: v1
kind: Service
metadata:
name: myapp-service
labels:
env: uat
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 9376
In the above template, if in our values.yaml file environment variable will be there then the template will generate with the label env otherwise it will not. For example if our values.yaml is this:
replicaCount: 1
image:
repository: nginx
tag: 1.21.6
pullPolicy: Always
Then our actual service.yaml
will be:
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Note: We add “-” sign next to the curly brackets to avoid extra whitespace/newlines in output.
This means remove whitespaces/newlines from the left.
{{-
This means remove whitespaces/newlines from the right.
-}}
Now Suppose in our case if environment is “uat” or any other like cug/prod, we need to print env label as it is. But if in values.yaml file environment mentioned as “sit” then we need to print env label as “dev”. Let’s see how can we do this using if/else blocks.
templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
{{- if .Values.environment }}
labels:
env: {{ .Values.environment }}
{{- else if eq .Values.environment "sit" }}
labels:
env: dev
{{- end }}
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Now if our values.yaml is this:
replicaCount: 1
image:
repository: nginx
tag: 1.21.6
pullPolicy: Always
environment: sit
Our actual service.yaml will be:
apiVersion: v1
kind: Service
metadata:
name: myapp-service
labels:
env: dev
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Here in templates/service.yaml
we used the “eq” expression to check the value of the environment variable is equal to sit or not. There are some other expressions in Helm that we can use in these types of situations.
eq ---> equal
ne ---> not equal
lt ---> less than
le ---> less than or equal to
gt ---> greater than
ge ---> greater than or equal to
not ---> negation
empty ---> value is empty
Let’s see another example.
values.yaml-
replicaCount: 1
image:
repository: nginx
tag: 1.21.6
pullPolicy: Always
serviceAccountName: myapp-sa
authorizationPolicy:
enabled: true
action: ALLOW
In this values.yaml
, we have two new variables serviceAccountName
and authorizationPolicy
. Let’s see how can we use these two to create serviceaccount for our app.
serviceaccount.yaml-
{{- if and .Values.authorizationPolicy.enabled .Values.serviceAccountName }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.serviceAccountName }}
{{- end }}
In serviceaccount.yaml
, we have added if condition with and expression. So in this case, if authorizationPolicy
is enabled and serviceAccountName
is there then Helm will create serviceaccount for our app otherwise it will skip.
Above are some basic examples of if/else block. Do play around it and see where we can add these conditions and make our templates more generic.
We will see with
and range
flow controls in the next article.