Now `{{ .Chart.Name }}` resolves to `mychart`, and `{{ .Chart.Version }}` resolves to `0.1.0`.
## Creating override-able sections with `block`
Say we want to create a template in our `_helpers.tpl` file, but then override part of its behavior in our template. This is what blocks are for. Sometimes we don't want to just insert a template with `template`, but we want to sketch out a default and let another template override our default. This makes it possible for one chart to define a base template, but allow another chart to strategically override some of its behavior.
Blocks are declared like this:
```yaml
{{ block "NAME" PIPELINE }}
{{ end }}
```
Here, "NAME" is the name that a `define` block can use to override it, and PIPELINE is the pipeline that will set the scope. So let's rewrite our `labels:` section to use this strategy. We'll create a basic labels section in our `_helpers.tpl` file, but add some extra labels in the `configmap.yaml` template.
Let's start with `_helpers.tpl`:
```yaml
{{- define "my_labels" }}
labels:
chart: {{ .Chart.Name }}
version: {{ .Chart.Version }}
{{ block "my_extra_labels" . }}extras: false{{ end }}
{{- end }}
```
Inside of our `my_labels` template, we now declare a block called `my_extra_labels`. By default, this section will have one extra label: `extras: false`. If we were to execute this using the same `configmap.yaml` file from last time, we'd get this:
```yaml
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: tinseled-womba-configmap
labels:
chart: mychart
version: 0.1.0
extras: false
data:
myvalue: "Hello World"
drink: "coffee"
food: "pizza"
```
But inside of our `configmap.yaml` template, we can override `my_extra_labels`:
```yaml
{{- define "my_extra_labels" }}chart: {{ .Chart.Name }}{{ end -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
{{- template "my_labels" . }}
data:
myvalue: "Hello World"
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}
```
On the first line, we redefine `my_extra_labels` to include `chart: {{ .Chart.Name }}`. If we
run this, we will get:
```yaml
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: ignorant-scorp-configmap
labels:
chart: mychart
version: 0.1.0
chart: mychart
data:
myvalue: "Hello World"
drink: "coffee"
food: "pizza"
```
Gone is the `extras: false` section, since that part of the template is now overridden by our new template, which placed `chart: mychart` into the output.
Blocks are not frequently used in Helm charts. But they do provide one mechanism for creating "abstract" charts, and then selectively overriding parts of the abstract template with concrete implementations.
## The `include` function
Say we've defined a simple template that looks like this:
@ -175,57 +175,33 @@ Globals are useful for passing information like this, though it does take some p
## Sharing Templates with Subcharts
Parent charts and subcharts can share templates. This can become very powerful when coupled with `block`s. For example, we can define a `block` in the `subchart` ConfigMap like this:
Parent charts and subcharts can share templates. Any defined block in any chart is
Note that the `from:` line says `mysubchart`. In a previous section, we created `mychart/templates/_helpers.tpl`. Let's define a new named template there called `labels` to match the declaration on the block above.
For example, we can define a simple template like this:
```yaml
{{- define "labels" }}from: mychart{{ end }}
```
Recall how the labels on templates are _globally shared_. That means that if we create a block named `labels` in one chart, and then define an override named `labels` in another chart, the override will be applied.
Recall how the labels on templates are _globally shared_. Thus, the `labels` chart
can be included from any other chart.
Now if we do a `helm install --dry-run --debug mychart`, it will override the block:
While chart developers have a choice between `include` and `template`, one advantage
of using `include` is that `include` can dynamically reference templates:
Now `from:` is set to `mychart` because the block was overridden.
The above will dereference `$mytemplate`. The `template` function, in contrast,
will only accept a string literal.
## Avoid Using Blocks
Using this method, you can write flexible "base" charts that can be added as subcharts to many different charts, and which will support selective overriding using blocks.
The Go template language provides a `block` keyword that allows developers to provide
a default implementation which is overridden later. In Helm charts, blocks are not
the best tool for overriding because it if multiple implementations of the same block
are provided, the one selected is unpredictable.
This section of the guide has focused on subcharts. We've seen how to inherit values, how to use global values, and how to override templates with blocks. In the next section we will turn to debugging, and learn how to catch errors in templates.
A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your charts works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do.
A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your chart works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do.
A **test** in a helm chart lives under the `templates/` directory and is a pod definition that specifies a container with a given command to run. The container should exit successfully (exit 0) for a test to be considered a success. The pod definiton must contain one of the helm test hook annotations: `helm.sh/hooks: test-success` or `helm.sh/hooks: test-failure`.
@ -17,12 +17,12 @@ You can run the pre-defined tests in Helm on a release using the command `helm t
In Helm, there are two test hooks: `test-success` and `test-failure`
`test-success` indiciates that test pod should complete successfully. In other words, the containers in the pod should exit 0.
`test-failure` is a way to assert that a test pod should not complete successfully. If the containers in the pod do not exit 0, that indiciates success.
`test-success` indicates that test pod should complete successfully. In other words, the containers in the pod should exit 0.
`test-failure` is a way to assert that a test pod should not complete successfully. If the containers in the pod do not exit 0, that indicates success.
## Example Test
Here is an example of a helm test pod definition in an example maraidb chart:
Here is an example of a helm test pod definition in an example mariadb chart:
@ -54,6 +54,7 @@ Tools layered on top of Helm or Tiller.
- [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes
- [Monocular](https://github.com/helm/monocular) - Web UI for Helm Chart repositories
- [Helm Chart Publisher](https://github.com/luizbafilho/helm-chart-publisher) - HTTP API for publishing Helm Charts in an easy way
- [Armada](https://github.com/att-comdev/armada) - Manage prefixed releases throughout various Kubernetes namespaces, and removes completed jobs for complex deployments. Used by the [Openstack-Helm](https://github.com/openstack/openstack-helm) team.
The above will set the default MariaDB user to `user0`, but accept all
the rest of the defaults for that chart.
The above will create a default MariaDB user with the name `user0`, and
grant this user access to a newly created `user0db` database, but will
accept all the rest of the defaults for that chart.
There are two ways to pass configuration data during install:
@ -355,7 +356,7 @@ is not a full list of cli flags. To see a description of all flags, just run
This defaults to 300 (5 minutes)
- `--wait`: Waits until all Pods are in a ready state, PVCs are bound, Deployments
have minimum (`Desired` minus `maxUnavailable`) Pods in ready state and
Services have and IP address (and Ingress if a `LoadBalancer`) before
Services have an IP address (and Ingress if a `LoadBalancer`) before
marking the release as successful. It will wait for as long as the
`--timeout` value. If timeout is reached, the release will be marked as
`FAILED`.
@ -473,6 +474,15 @@ Note: The `stable` repository is managed on the [Kubernetes Charts
GitHub repository](https://github.com/kubernetes/charts). That project
accepts chart source code, and (after audit) packages those for you.
## Tiller, Namespaces and RBAC
In some cases you may wish to scope Tiller or deploy multiple Tillers to a single cluster. Here are some best practices when operating in those circumstances.
1. Tiller can be [installed](install.md) into any namespace. By default, it is installed into kube-system. You can run multiple Tillers provided they each run in their own namespace.
2. Limiting Tiller to only be able to install into specific namespaces and/or resource types is controlled by Kubernetes [RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) roles and rolebindings.
3. Release names are unique PER TILLER INSTANCE.
4. Charts should only contain resources that exist in a single namespace.
5. It is not recommended to have multiple Tillers configured to manage resources in the same namespace.
## Conclusion
This chapter has covered the basic usage patterns of the `helm` client,
{name:"full URL, with authentication",ref:"http://username:password@example.com/foo-1.2.3.tgz",expect:"http://username:password@example.com/foo-1.2.3.tgz"},