Getting Started with a Chart Template

In this section of the guide, we’ll create a chart and then add a first template. The chart we created here will be used throughout the rest of the guide.

To get going, let’s take a brief look at a Helm chart.

Charts

As described in the Charts Guide, Helm charts are structured likethis:

  1. mychart/
  2. Chart.yaml
  3. values.yaml
  4. charts/
  5. templates/
  6. ...

The templates/ directory is for template files. When Tiller evaluates a chart,it will send all of the files in the templates/ directory through thetemplate rendering engine. Tiller then collects the results of those templatesand sends them on to Kubernetes.

The values.yaml file is also important to templates. This file contains thedefault values for a chart. These values may be overridden by users duringhelm install or helm upgrade.

The Chart.yaml file contains a description of the chart. You can access itfrom within a template. The charts/ directory may contain other charts (whichwe call subcharts). Later in this guide we will see how those work when itcomes to template rendering.

A Starter Chart

For this guide, we’ll create a simple chart called mychart, and then we’llcreate some templates inside of the chart.

  1. $ helm create mychart
  2. Creating mychart

From here on, we’ll be working in the mychart directory.

A Quick Glimpse of mychart/templates/

If you take a look at the mychart/templates/ directory, you’ll notice a few filesalready there.

  • NOTES.txt: The “help text” for your chart. This will be displayed to your userswhen they run helm install.
  • deployment.yaml: A basic manifest for creating a Kubernetes deployment
  • service.yaml: A basic manifest for creating a service endpoint for your deployment
  • _helpers.tpl: A place to put template helpers that you can re-use throughout the chart

And what we’re going to do is… remove them all! That way we can work through our tutorial from scratch. We’ll actually create our own NOTES.txt and _helpers.tpl as we go.

  1. $ rm -rf mychart/templates/*.*

When you’re writing production grade charts, having basic versions of these charts can be really useful. So in your day-to-day chart authoring, you probably won’t want to remove them.

A First Template

The first template we are going to create will be a ConfigMap. In Kubernetes,a ConfigMap is simply a container for storing configuration data. Other things,like pods, can access the data in a ConfigMap.

Because ConfigMaps are basic resources, they make a great starting point for us.

Let’s begin by creating a file called mychart/templates/configmap.yaml:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: mychart-configmap
  5. data:
  6. myvalue: "Hello World"

TIP: Template names do not follow a rigid naming pattern. However, we recommendusing the suffix .yaml for YAML files and .tpl for helpers.

The YAML file above is a bare-bones ConfigMap, having the minimal necessary fields.In virtue of the fact that this file is in the templates/ directory, it willbe sent through the template engine.

It is just fine to put a plain YAML file like this in the templates/ directory.When Tiller 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 installit like this:

  1. $ helm install ./mychart
  2. NAME: full-coral
  3. LAST DEPLOYED: Tue Nov 1 17:36:01 2016
  4. NAMESPACE: default
  5. STATUS: DEPLOYED
  6. RESOURCES:
  7. ==> v1/ConfigMap
  8. NAME DATA AGE
  9. mychart-configmap 1 1m

In the output above, we can see that our ConfigMap was created. Using Helm, wecan retrieve the release and see the actual template that was loaded.

  1. $ helm get manifest full-coral
  2. ---
  3. # Source: mychart/templates/configmap.yaml
  4. apiVersion: v1
  5. kind: ConfigMap
  6. metadata:
  7. name: mychart-configmap
  8. data:
  9. myvalue: "Hello World"

The helm get manifest command takes a release name (full-coral) and printsout all of the Kubernetes resources that were uploaded to the server. Each filebegins with —- to indicate the start of a YAML document, and then is followedby an automatically generated comment line that tells us what template filegenerated this YAML document.

From there on, we can see that the YAML data is exactly what we put in ourconfigmap.yaml file.

Now we can delete our release: helm delete full-coral.

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 fieldby inserting the release name.

TIP: The name: field is limited to 63 characters because of limitations tothe 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.

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: {{ .Release.Name }}-configmap
  5. data:
  6. myvalue: "Hello World"

The big change comes in the value of the name: field, which is now{{ .Release.Name }}-configmap.

A template directive is enclosed in {{ and }} blocks.

The template directive {{ .Release.Name }} injects the release name into the template. The values that are passed into a template can be thought of as namespaced objects, where a dot (.) separates each namespaced element.

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, and we’ll cover it in more depth later. But for now, it is sufficient to say that this will display the release name that Tiller assigns to our release.

Now when we install our resource, we’ll immediately see the result of using this template directive:

  1. $ helm install ./mychart
  2. NAME: clunky-serval
  3. LAST DEPLOYED: Tue Nov 1 17:45:37 2016
  4. NAMESPACE: default
  5. STATUS: DEPLOYED
  6. RESOURCES:
  7. ==> v1/ConfigMap
  8. NAME DATA AGE
  9. clunky-serval-configmap 1 1m

Note that in the RESOURCES section, the name we see there is clunky-serval-configmapinstead of mychart-configmap.

You can run helm get manifest clunky-serval to see the entire generated YAML.

At this point, we’ve seen templates at their most basic: YAML files that have template directives embedded in {{ and }}. In the next part, we’ll take a deeper look into templates. But before moving on, there’s one quick trick that can make building templates faster: When you want to test the template rendering, but not actually install anything, you can use helm install ./mychart —debug —dry-run. This will send the chart to the Tiller server, which will render the templates. But instead of installing the chart, it will return the rendered template to you so you can see the output:

  1. $ helm install ./mychart --debug --dry-run
  2. SERVER: "localhost:44134"
  3. CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart
  4. NAME: goodly-guppy
  5. TARGET NAMESPACE: default
  6. CHART: mychart 0.1.0
  7. MANIFEST:
  8. ---
  9. # Source: mychart/templates/configmap.yaml
  10. apiVersion: v1
  11. kind: ConfigMap
  12. metadata:
  13. name: goodly-guppy-configmap
  14. data:
  15. myvalue: "Hello World"

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.

In the next few sections, we’ll take the basic chart we defined here and explore the Helm template language in detail. And we’ll get started with built-in objects.