Helm for Kubernetes - Managing Dependencies

In this article, we'll cover how to manage Helm chart dependencies end to end — from packaging a chart into a .tgz archive and publishing it to a Helm chart repository, to declaring subcharts in Chart.yaml, toggling them with condition and tags, and passing configuration between parent and child charts using overrides and import-values.

Series — Helm for Kubernetes:

  1. Basic Concepts
  2. Templates and functions
  3. Managing Dependencies (you are here)

Packaging a Helm Chart with helm package

Before publishing a chart in a repository, we need to package it. Packaging a chart creates a versioned .tgz file that can be shared and installed on other Kubernetes clusters. This is an important step in managing dependencies, as it allows us to define and use external charts as dependencies in our own charts.

When we create a Helm chart, we can package it into a .tgz file using the helm package command. This command takes the chart directory as input and creates a compressed archive of the chart, which can be shared and installed on other Kubernetes clusters.

Copy
helm package mychart/

Publishing a Helm Chart to a Chart Repository

Once we have packaged our chart, we can publish it in a Helm chart repository. A Helm chart repository is a collection of packaged charts that can be shared and installed by others. There are public repositories, such as the Helm Stable repository, and you can also create your own private repository for internal use.

To publish a chart, we need to upload the .tgz file to the repository. The exact steps depend on the type of repository you are using.

To add or remove a chart repository, we can use the helm repo add and helm repo remove commands. For example, to add the stable repository, we can run:

Copy
helm repo add stable https://charts.helm.sh/stable
helm repo add my-repo http://myserver.org/charts
helm repo remove my-repo

Last, to push a chart to a repository, we can use the helm push command. This command takes the .tgz file and uploads it to the specified repository.

Copy
helm push mychart-0.1.0.tgz my-repo

How to Declare Helm Chart Dependencies in Chart.yaml

Previously, we saw how to define an umbrella chart that includes other charts as dependencies in the charts directory. This is a manual way of managing dependencies, but Helm also provides a more convenient way to manage dependencies using the Chart.yaml file.

Helm allows you to define dependencies in your chart's Chart.yaml file. Dependencies are other charts that your chart depends on. By specifying dependencies, Helm can automatically download and install the required charts when you install your chart.

Copy
apiVersion: v2
name: mychart
version: 0.1.0
type: application
dependencies:
  - name: redis
    version: ~14.8.8
    repository: https://charts.helm.sh/stable
  - name: postgresql
    version: ^10.3.0
    repository: http://localhost:8080/charts
  - name: nginx
    version: 9.3.x
    repository: https://charts.bitnami.com/bitnami

Enabling Helm Dependencies with Conditions and Tags

Helm allows you to manage dependencies using conditions and tags. Conditions are boolean values that determine whether a dependency should be enabled or disabled. Tags are labels that can be used to group dependencies and enable or disable them together.

For example, we can define a condition for the redis or postgresql dependencies in our Chart.yaml file, based on values in the values.yaml file. If the condition evaluates to true, the dependency will be enabled; otherwise, it will be disabled.

Copy
dependencies:
  - name: redis
    version: ~14.8.8
    repository: https://charts.helm.sh/stable
    condition: redis.enabled
  - name: postgresql
    version: ^10.3.0
    repository: http://localhost:8080/charts
    condition: backend.enabled,postgresql.enabled
Copy
# values.yaml
redis:
  enabled: true
backend:
  enabled: true
postgresql:
  enabled: false

Similar to conditions, we can use tags to group dependencies and enable or disable them together. For example, we can define a tag for the redis and postgresql dependencies in our Chart.yaml file. If the tag is enabled, both dependencies will be enabled; otherwise, they will be disabled.

Copy
dependencies:
  - name: redis
    version: ~14.8.8
    repository: https://charts.helm.sh/stable
    tags:
      - database
  - name: postgresql
    version: ^10.3.0
    repository: http://localhost:8080/charts
    tags:
      - database
Copy
# values.yaml
tags:
  database: true

It is important to remark that conditions overwrite tags if both are defined for a dependency. If a dependency has both a condition and a tag, the condition will take precedence over the tag.

Overriding Subchart Values from the Parent Chart

When using dependencies in Helm charts, we can customize their behavior by passing values to them. This allows us to configure the dependencies according to our needs. For example, we can set the number of replicas for a dependent chart or configure its resource limits, or adding username and password for a database chart. We can do this by defining values in our chart's values.yaml file and passing them to the dependencies.

Copy
# Chart.yaml
apiVersion: v2
name: mychart
version: 0.1.0
type: application
dependencies:
  - name: redis
    version: ~14.8.8
    repository: https://charts.helm.sh/stable
    condition: redis.enabled
  - name: postgresql
    version: ^10.3.0
    repository: http://localhost:8080/charts
    condition: postgresql.enabled
Copy
# values.yaml
redis:  # Should match the name of the dependency defined in Chart.yaml
  enabled: true
  replicaCount: 3
postgresql:  # Should match the name of the dependency defined in Chart.yaml
  enabled: true
  postgresqlUsername: myuser
  postgresqlPassword: mypassword

These are saved in the values.yaml file of our chart (the parent chart), and will overwrite the default values of the dependent charts. This allows us to customize the behavior of the dependencies without modifying their source code.

Copy
|-- mychart/
|   |-- Chart.yaml
|   |-- values.yaml      <-- Parent chart values, where we can define values for the dependencies
|   |-- charts/
|   |   |-- redis/       <-- Dependency coming from a repository, with its own values.yaml file
|   |   |   |-- templates/
|   |   |   |-- Chart.yaml
|   |   |   |-- values.yaml
|   |   |-- postgresql/      <-- Dependency coming from a repository, with its own values.yaml file
|   |   |   |-- templates/
|   |   |   |-- Chart.yaml
|   |   |   |-- values.yaml

Exporting and Importing Values Between Parent and Child Charts

Overwriting works good, but there are also other more explicit ways to manage values between parent and child charts, like exporting and importing values.

From the child chart, we can export values to the parent chart using the export keyword in the values.yaml file of the child chart. This allows us to pass values from the child chart to the parent chart, which can be useful for configuring the parent chart based on the behavior of the child chart.

Copy
# values.yaml of the child chart (e.g., redis)
export:
  data:
    redisPassword: mypassword

From the parent chart, we can import values from the child chart using the import-values keyword in the Chart.yaml file of the parent chart. This allows us to use values from the child chart in the parent chart, which can be useful for configuring the parent chart based on the behavior of the child chart.

Copy
# Chart.yaml of the parent chart (e.g., mychart)
...
dependencies:
  - name: redis
    version: ~14.8.8
    repository: https://charts.helm.sh/stable
    import-values:
      - child: data
        parent: redis_data

Now we can access the redisPassword value from the child chart in the parent chart using the redis_data.redisPassword key.

Copy
# values.yaml of the parent chart (e.g., mychart)
redis_data:
  redisPassword: mypassword

And anywhere in the parent chart templates, we can access the value using {{ .Values.redis_data.redisPassword }}.

helm dependency and helm repo Command Reference

Helm provides several commands for managing dependencies and repositories. Here are some useful commands:

  • <url: Add a new chart repository.
  • helm repo remove <name>: Remove a chart repository.
  • helm repo update: Update the local cache of chart repositories.
  • helm repo list: List all chart repositories.
  • helm search repo <keyword>: Search for charts in the repositories.
  • helm dependency update <chart>: Update the dependencies for a chart.
  • helm dependency build <chart>: Build the dependencies for a chart.
  • helm dependency list <chart>: List the dependencies for a chart.
  • <dependency: Add a new dependency to a chart.
  • <dependency: Remove a dependency from a chart.

Wrap up the Helm series and connect it back to the wider Kubernetes stack: