Helm Template
helm create mychart
cd mychart
The first template we are going to create will be a ConfigMap.
Let’s begin by creating a file called mychart/templates/configmap.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart
data:
myvalue: "Hello World"
It is just fine to put a plain YAML file like this in the mychart/templates/ directory. When Helm reads this template, it will simply send it to Kubernetes as-is.
With this simple template, we now have an installable chart. And we can install it like this:
helm install first ./mychart
Using Helm, we can retrieve the release and see the actual template that was loaded.
helm get manifest first
The helm get manifest command takes a release name (first) and prints out all of the Kubernetes resources that were uploaded to the server.
Now we can uninstall our release: helm uninstall first
Adding a Simple Template Call
Hard-coding the name: into a resource is usually considered to be bad practice. Names should be unique to a release. So we might want to generate a name field by inserting the release name.
The name: field is limited to 63 characters because of limitations to the DNS system. For that reason, release names are limited to 53 characters. Kubernetes 1.3 and earlier limited to only 24 characters (thus 14 character names).
Let’s alter configmap.yaml accordingly.
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
The leading dot before Release indicates that we start with the top-most namespace for this scope (we’ll talk about scope in a bit). So we could read .Release.Name as “start at the top namespace, find the Release object, then look inside of it for an object called Name”.
The Release object is one of the built-in objects for Helm.
helm install first ./mychart
helm get manifest first
When you want to test the template rendering, but not actually install anything, you can use
helm install --debug --dry-run first ./mychart. This will render the templates. But instead of installing the chart, it will return the rendered template to you so you can see the output:
Using --dry-run will make it easier to test your code, but it won’t ensure that Kubernetes itself will accept the templates you generate. It’s best not to assume that your chart will install just because --dry-run works.
Built-in Objects
Objects can be simple, and have just one value. Or they can contain other objects or functions. For example, the Release object contains several objects (like Release.Name) and the Files object has a few functions.
1. Release
Release: This object describes the release itself. It has several objects inside of it:Release.Name: The release nameRelease.Namespace: The namespace to be released into (if the manifest doesn’t override)Release.IsUpgrade: This is set to true if the current operation is an upgrade or rollback.Release.IsInstall: This is set to true if the current operation is an install.Release.Revision: The revision number for this release. On install, this is 1, and it is incremented with each upgrade and rollback.Release.Service: The service that is rendering the present template. On Helm, this is alwaysHelm.
-
Values: Values passed into the template from the values.yaml file and from user-supplied files. By default, Values is empty.
- Chart: The contents of the Chart.yaml file. Any data in Chart.yaml will be accessible here. For example {{ .Chart.Name }}-{{ .Chart.Version }} will print out the mychart-0.1.0
Example
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
labels:
{{ .Chart.Version }}: {{ .Chart.Name }}
data:
myvalue: "Hello World"
2. Subcharts
Subcharts:This provides access to the scope (.Values, .Charts, .Releases etc.) of subcharts to the parent. For example.Subcharts.mySubChart.myValueto access themyValuein themySubChartchart.
3. Files
{{: .note}}
Sometimes it is desirable to import a file that is not a template and inject its contents without sending the contents through the template renderer.
Helm provides access to files through the .Files object. Before we get going with the template examples, though, there are a few things to note about how this works:
-
It is okay to add extra files to your Helm chart. These files will be bundled. Be careful, though. Charts must be smaller than 1M because of the storage limitations of Kubernetes objects.
- Some files cannot be accessed through the
.Filesobject, usually for security reasons.- Files in
templates/cannot be accessed. - Files excluded using
.helmignorecannot be accessed. - Files outside of a Helm application subchart, including those of the parent, cannot be accessed
- Files in
-
Charts do not preserve
UNIXmode information, so file-level permissions will have no impact on the availability of a file when it comes to the.Filesobject. - Files: This provides access to all non-special files in a chart. While you cannot use it to access templates, you can use it to access other files in the chart.
Files.Getis a function for getting a file by name (.Files.Get config.ini)Files.GetBytesis a function for getting the contents of a file as an array of bytes instead of as a string. This is useful for things like images.Files.Globis a function that returns a list of files whose names match the given shell glob pattern.Files.Linesis a function that reads a file line-by-line. This is useful for iterating over each line in a file.Files.AsSecretsis a function that returns the file bodies as Base 64 encoded strings.Files.AsConfigis a function that returns file bodies as a YAML map.
Accessing Files Inside Templates
Let’s write a template that reads three files into our ConfigMap. To get started, we will add three files to the chart, putting all three directly inside of the mychart/ directory.
touch config1.toml && echo "message = Hello from config 1" >> config1.toml
touch config2.toml && echo "message = Hello from config 2" >> config2.toml
touch config3.toml && echo "message = Hello from config 3" >> config3.toml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
{{- $files := .Files }}
{{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
{{ . }}: |-
{{ $files.Get . }}
{{- end }}
We create a $files variable to hold a reference to the .Files object. We also use the tuple function to create a list of files that we loop through. Then we print each file name ({{ . }}: |-) followed by the contents of the file {{ $files.Get . }}.
Path helpers
When working with files, it can be very useful to perform some standard operations on the file paths themselves. To help with this, Helm imports many of the functions from Go’s path package for your use. They are all accessible with the same names as in the Go package, but with a lowercase first letter. For example, Base becomes base, etc.
The imported functions are:
- Base
- Dir
- Ext
- IsAbs
- Clean
a). Base (Filename Extraction)
- Gets the last element of the path (i.e., filename).
{{- $filePath := "config1.toml" }}
{{- $fileName := base $filePath }}
Filename: {{ $fileName }}
b). Dir (Parent Directory Extraction)
- Gets the directory portion of a path.
{{- $dirName := dir "configs/config1.toml" }}
Directory: {{ $dirName }}
c). Ext (File Extension Extraction)
- Gets the file extension.
{{- $ext := ext "configs/config1.toml" }}
Extension: {{ $ext }}
d). IsAbs (Check if Path is Absolute)
- Checks if a path is absolute.
path_type: |- # Added key `path_type`
{{- if isAbs "/etc/config1.toml" }}
This is an absolute path.
{{- else }}
This is a relative path.
{{- end }}
e). Clean (Normalize the Path)
- Removes redundant
slashesor..components.
{{- $cleanedPath := clean "configs//../config1.toml" }}
Cleaned Path: {{ $cleanedPath }}
{{: .important}}
All the path helpers with example
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
{{- $files := .Files }}
{{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
{{ . }}: |-
{{ $files.Get . }}
{{- end }}
# base
{{- $filePath := "config1.toml" }}
{{- $fileName := base $filePath }}
Filename: {{ $fileName }}
# isAbs
path_type: |- # Added key `path_type`
{{- if isAbs "/etc/config1.toml" }}
This is an absolute path.
{{- else }}
This is a relative path.
{{- end }}
# ext
{{- $ext := ext "configs/config1.toml" }}
Extension: {{ $ext }}
# dir
{{- $dirName := dir "configs/config1.toml" }}
Directory: {{ $dirName }}
#clean
{{- $cleanedPath := clean "configs//../config1.toml" }}
Cleaned Path: {{ $cleanedPath }}
Encoding
You can import a file and have the template base-64 encode it to ensure successful transmission:
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-secret
type: Opaque
data:
token: |-
{{ .Files.Get "config1.toml" | b64enc }}
4. Capabilities
Capabilities: This provides information about what capabilities the Kubernetes cluster supports.Capabilities.APIVersionsis a set of versions.Capabilities.APIVersions.Has$version indicates whether a version (e.g.,batch/v1) or resource (e.g., apps/v1/Deployment) is available on the cluster.Capabilities.KubeVersionandCapabilities.KubeVersion.Versionis the Kubernetes version.Capabilities.KubeVersion.Majoris the Kubernetes major version.Capabilities.KubeVersion.Minoris the Kubernetes minor version.Capabilities.HelmVersionis the object containing the Helm Version details, it is the same output of helm version.Capabilities.HelmVersion.Versionis the current Helm version in semver format.Capabilities.HelmVersion.GitCommitis the Helm git sha1.Capabilities.HelmVersion.GitTreeStateis the state of the Helm git tree.Capabilities.HelmVersion.GoVersionis the version of the Go compiler used.
Example:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
labels:
kube-version: {{ .Capabilities.KubeVersion }}
kube-versionn: {{ .Capabilities.KubeVersion.Version }}
data:
{{- $files := .Files }}
{{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
{{ . }}: |-
{{ $files.Get . | nindent 4 }}
{{- end }}
Template
Template: Contains information about the current template that is being executedTemplate.Name: A namespaced file path to the current template (e.g.mychart/templates/mytemplate.yaml)Template.BasePath: The namespaced path to the templates directory of the current chart (e.g.mychart/templates).