Define Scope in helm
In this tutorial, we will discuss how to define scope in helm using with a keyword. I can create a block of restricted scope using with a keyword.
{{ with PIPELINE }}
# restricted scope
{{ end }}
I can have a with and then a pipeline where It’s going to evaluate a condition, or it’s going to read a collection of values.
So once the condition is evaluated, it will execute the collection of statements within the block. And the value that got evaluated using the pipeline will be available or can be used only within that specific block, within the restricted scope.
Example
Let us understand using a small demo. Let me get into the chart that we had created. Now let me add some sample values. I’m going to edit the values file.
I’m going to add a key called tags, and it’s going to have a collection of key-value pairs like programming as key and java as value. Like that, I have some key and value pairs within the key tags.
ashok@waytoeasylearn:~/mychart$ cat values.yaml
message: Welcome to waytoeasylearn
website: www.waytoeasylearn.com
owner:
name: Ashok Kumar
place: Hyderabad
tags:
programming: java
devops: kubernetes
deployment: helm
bigdata: hadoop
So this is something like a map, or we can visualize this as a collection as well. Now I’m going to change the template.
So within the template, I’m going to add the with condition, and I will read the values.tags, observe the white spaces.
And the key-value pair, I am adding it in the same indent where I am evaluating with I am adding the keyword then I’m getting the Values.tags.
ashok@waytoeasylearn:~/mychart$ cat templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Sample Config Map"
message: {{ .Values.message }}
website: {{ upper .Values.website }}
ownerName: {{ quote .Values.owner.name }}
ownerPlace: {{ quote .Values.owner.place }}
{{- with .Values.tags }}
Programming: {{ .programming | default "NA" | quote }}
DevOps: {{ .devops | quote }}
Deployment: {{ .deployment | upper | quote }}
BigData: {{ .bigdata | quote }}
{{- end }}
So all the values within the tags will be available only within this specific scope. Within this particular scope, the built-in objects will also not be accessible. We will do that as a separate tutorial.
Now I’m going to use this specific values.tag as a with and directly I can access .programming because the parent scope of this particular block is tags.
So within the tags, I can access the devops, deployment, programming, and bigdata. Let me go ahead and execute the dry run.
ashok@waytoeasylearn:~$ helm install --debug --dry-run definescope ./mychart/
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: /home/ashok/mychart
NAME: definescope
LAST DEPLOYED: Fri May 21 11:08:15 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
message: Welcome to waytoeasylearn
owner:
name: Ashok Kumar
place: Hyderabad
qualification: mca
tags:
bigdata: hadoop
deployment: helm
devops: kubernetes
programming: java
website: www.waytoeasylearn.com
HOOKS:
MANIFEST:
Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: definescope-configmap
data:
myvalue: "Sample Config Map"
message: Welcome to waytoeasylearn
website: WWW.WAYTOEASYLEARN.COM
ownerName: "Ashok Kumar"
ownerPlace: "Hyderabad"
Programming: "java"
DevOps: "kubernetes"
Deployment: "HELM"
BigData: "hadoop"
So the condition got evaluated, and it read the Values java, kubernetes, HELM, and hadoop, and it got printed here.
how the indent can be used
Now let’s go ahead and try another scenario of how can use the indent. Getting into the template here, the same values from the tags I will read and add as a part of the labels.
ashok@waytoeasylearn:~/mychart$ cat templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
labels:
{{- with .Values.tags }}
first: {{ .programming }}
second: {{ .devops }}
thrid: {{ .deployment }}
{{- end }}
data:
myvalue: "Sample Config Map"
message: {{ .Values.message }}
website: {{ upper .Values.website }}
ownerName: {{ quote .Values.owner.name }}
ownerPlace: {{ quote .Values.owner.place }}
{{- with .Values.tags }}
Programming: {{ .programming | default "NA" | quote }}
DevOps: {{ .devops | quote }}
Deployment: {{ .deployment | upper | quote }}
BigData: {{ .bigdata | quote }}
{{- end }}
This is another good example of how to use white space, so within labels, I will have a first, second, and third set.
The values will be picked because I am using with keyword within that particular block. So it’s going to read all the values from the tags, and all the references within that specific block will be to the scope of that particular tag only.
So within the tags, it’s going to read programming, devops and deployment. And with the same indent, it’s going to print the values; let me go ahead and do a dry run.
ashok@waytoeasylearn:~$ helm install --debug --dry-run definescope ./mychart/
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: /home/ashok/mychart
NAME: definescope
LAST DEPLOYED: Fri May 21 11:22:42 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
message: Welcome to waytoeasylearn
owner:
name: Ashok Kumar
place: Hyderabad
qualification: mca
tags:
bigdata: hadoop
deployment: helm
devops: kubernetes
programming: java
website: www.waytoeasylearn.com
HOOKS:
MANIFEST:
Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: definescope-configmap
labels:
first: java
second: kubernetes
thrid: helm
data:
myvalue: "Sample Config Map"
message: Welcome to waytoeasylearn
website: WWW.WAYTOEASYLEARN.COM
ownerName: "Ashok Kumar"
ownerPlace: "Hyderabad"
Programming: "java"
DevOps: "kubernetes"
Deployment: "HELM"
BigData: "hadoop"
So within labels, I have three labels with the key and value, which got added. So the white space Indent is very, very important.
Add Builtin objects with in scope
Now, let’s go ahead and add something which is not there within the scope. So within this specific block, I’m going to access the built-in object release.name
ashok@waytoeasylearn:~/mychart$ cat templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
labels:
{{- with .Values.tags }}
first: {{ .programming }}
second: {{ .devops }}
thrid: {{ .deployment }}
{{- end }}
data:
myvalue: "Sample Config Map"
message: {{ .Values.message }}
website: {{ upper .Values.website }}
ownerName: {{ quote .Values.owner.name }}
ownerPlace: {{ quote .Values.owner.place }}
{{- with .Values.tags }}
Programming: {{ .programming | default "NA" | quote }}
DevOps: {{ .devops | quote }}
Deployment: {{ .deployment | upper | quote }}
BigData: {{ .bigdata | quote }}
Release: {{ .Release.Name }}
{{- end }}
Within the tags, I will not have anything with release or name. So there should not be any value getting printed for this.
Let me go ahead and do a dry run. It is not getting any value.
ashok@waytoeasylearn:~$ helm install --debug --dry-run definescope ./mychart/
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: /home/ashok/mychart
Error: template: mychart/templates/configmap.yaml:22:22: executing "mychart/templates/configmap.yaml" at <.Release.Name>: nil pointer evaluating interface {}.Name
helm.go:81: [debug] template: mychart/templates/configmap.yaml:22:22: executing "mychart/templates/configmap.yaml" at <.Release.Name>: nil pointer evaluating interface {}.Name
So the YAML turned out to be a not valid template, and there are some options to solve this particular problem; definitely, there will be a need to access the built-in objects within the blocks, and we can solve it using variables.
We will be discussing variables in future tutorials. Now I can add this particular release name outside the restricted block, and that should work.
ashok@waytoeasylearn:~/mychart$ cat templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
labels:
{{- with .Values.tags }}
first: {{ .programming }}
second: {{ .devops }}
thrid: {{ .deployment }}
{{- end }}
data:
myvalue: "Sample Config Map"
message: {{ .Values.message }}
website: {{ upper .Values.website }}
ownerName: {{ quote .Values.owner.name }}
ownerPlace: {{ quote .Values.owner.place }}
{{- with .Values.tags }}
Programming: {{ .programming | default "NA" | quote }}
DevOps: {{ .devops | quote }}
Deployment: {{ .deployment | upper | quote }}
BigData: {{ .bigdata | quote }}
{{- end }}
Release: {{ .Release.Name }}
Let me go ahead and do a dry run.
ashok@waytoeasylearn:~$ helm install --debug --dry-run definescope ./mychart/
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: /home/ashok/mychart
NAME: definescope
LAST DEPLOYED: Fri May 21 11:22:42 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
message: Welcome to waytoeasylearn
owner:
name: Ashok Kumar
place: Hyderabad
qualification: mca
tags:
bigdata: hadoop
deployment: helm
devops: kubernetes
programming: java
website: www.waytoeasylearn.com
HOOKS:
MANIFEST:
Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: definescope-configmap
labels:
first: java
second: kubernetes
thrid: helm
data:
myvalue: "Sample Config Map"
message: Welcome to waytoeasylearn
website: WWW.WAYTOEASYLEARN.COM
ownerName: "Ashok Kumar"
ownerPlace: "Hyderabad"
Programming: "java"
DevOps: "kubernetes"
Deployment: "HELM"
BigData: "hadoop"
Release: definescope
And yes, it’s able to read the release name. So basically, within the restricted block, we cannot use the values from other scope or even the built-in objects.
We cannot access it, and that should be accessed using the variables. And this restricted block will be very useful whenever I want to iterate over a given set of values or arrays. It will be very useful so that I can work only on that restricted set of values.
So in a quick summary, we have seen how to define scope using the with keyword.