Helm Chart Dependencies

Helm charts serve as a package manager for Kubernetes, facilitating the definition, installation, and upgrade of Kubernetes applications. One of the most important components in Helm is chart dependencies. Instead of writing all configurations from scratch, you can use pre-existing charts as dependencies to extend the functionality of a new chart.

In this blog, we will learn what Helm Chart Dependencies are and how to use them.

Want to learn more about creating Helm Charts? Read this blog: Writing a Helm Chart: A Comprehensive Guide for Beginners.

What are Helm Chart Dependencies?

Helm chart dependencies are other charts that a Helm chart relies on to function correctly. These dependencies are specified in the chart directory's requirements.yaml file, which lists the chart name, version, and repository URL that the main chart requires.

If a chart has dependencies, Helm will automatically download and install them before installing the main chart. This guarantees that all necessary elements are available and correctly configured.

Updating dependencies is also possible by using the helm dependency update command, which downloads the latest version of each dependency and updates the Chart.lock file accordingly. This ensures that the chart is current and all dependencies are compatible with one another.

How to Add a Dependency to Helm Chart

If we were to build a chart to launch a WordPress website, it would also depend on a chart for MySQL or MariaDB and, possibly, Memcached if we want to add a way to speed up the website.

There are two ways to add dependency charts to our main parent chart:

  1. Listing dependencies in our Chart.yaml file and then let Helm download the necessary dependency files.
  2. Dropping dependency charts (the files and directories they contain) manually in the charts directory.

1. Listing dependencies in Chart.yaml

Let’s assume that, for some reason, our chart would need MariaDB. To add it as a dependency, open up our Chart.yaml file in an Editor.

Under the description of our chart, we need to add this content:

dependencies:
  - name: mariadb
    repository: https://charts.bitnami.com/bitnami
    version: ~9.3

Our Chart.yaml file now looks like this:

apiVersion: v2
name: nginx
description: Basic Nginx website for our company

dependencies:
  - name: mariadb
    repository: https://charts.bitnami.com/bitnami
    version: ~9.3

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"

maintainers:
- email: [email protected]
  name: John Smith

Let’s analyze two components in the content we added: repository and version.

repository: https://charts.bitnami.com/bitnami

How do we get that address? Well, in our case, we looked up a chart on the Artifact Hub website and ended up choosing this as a proper candidate. We can see there that the command to add this repository to Helm is:

The address we add to our repository: field is the same one we would use in a helm repo add command.

helm repo add bitnami https://charts.bitnami.com/bitnami

Now, the second interesting line:

version: ~9.3

What does ~9.3 mean, and why did we choose to use this version?

At the time of creating this blog, when we opened up this, we noticed that this chart’s latest version was 9.3.16.

Using the notation ~9.3 in our version: field ensures that our chart will pull in the latest version of the MariaDB chart, which starts with 9.3. This could be 9.3.16 today and 9.3.18 a few weeks later. But it won’t pull in a version that starts with 9.4.

This is a good way to make sure we pull the latest chart version with a certain feature set that is currently compatible with our parent chart. Versions 9.4 and 9.5 might introduce feature changes that make them incompatible with the current parent chart.

But we did not analyze the first line:

- name: mariadb

The name is pretty straightforward. We just use the chart name we want to use as a dependency. It’s the same name we would use when installing such a chart with a command like:

helm install my-release bitnami/mariadb

But the - sign might be a bit weird. It’s just standard YAML stuff to delimit multiple children of the dependencies: section. To make it easier to remember how to write this, you can think of it this way:

Since we list multiple chart dependencies here, we need a way to delimit where one dependency declaration ends and another begins. So, we use the “-” sign to separate the details of each dependency chart.

Here’s an example with multiple dependencies:

dependencies:
- condition: mariadb.enabled
  name: mariadb
  repository: https://charts.bitnami.com/bitnami
  version: 9.x.x
- condition: memcached.enabled
  name: memcached
  repository: https://charts.bitnami.com/bitnami
  version: 5.x.x
- name: common
  repository: https://charts.bitnami.com/bitnami
  tags:
  - bitnami-common
  version: 1.x.x

(The “-“ in the tags: section is different. You could think of “-” as separating children of the tags: section)

All in all, it was pretty easy to add our MariaDB dependency. But the job is not done, though. This just tells Helm about the dependency charts, but the dependency charts themselves are still missing from our project. Fortunately, there is a simple command that makes Helm look at our dependency list (in Chart.yaml) and automatically pull in all of the required charts (their files):

helm dependency update ./nginx

And that’s it, job done! The command helm template ./nginx will show us that, indeed, now the MariaDB dependency chart is included in our parent chart:

user@debian:~$ helm template ./nginx
---
# Source: nginx/charts/mariadb/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: RELEASE-NAME-mariadb
  namespace: default
  labels:
    app.kubernetes.io/name: mariadb
    helm.sh/chart: mariadb-9.3.16
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/managed-by: Helm
  annotations:
---
# Source: nginx/charts/mariadb/templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: RELEASE-NAME-mariadb
  namespace: default
  labels:
    app.kubernetes.io/name: mariadb
    helm.sh/chart: mariadb-9.3.16
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/managed-by: Helm
type: Opaque
data:
  mariadb-root-password: "Q0tHdHJMTE5xdw=="
  mariadb-password: "anE1bmJ6TEhwYg=="
---

To prepare for our next exercise, let’s remove MariaDB from the list of dependencies in Chart.yaml as

dependencies:
  - name: mariadb
    repository: https://charts.bitnami.com/bitnami
    version: ~9.3

The final content will be:

apiVersion: v2
name: nginx
description: Basic Nginx website for our company

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"

maintainers:
- email: [email protected]
  name: John Smith

2. Adding Dependencies Manually in the “charts” Directory

Although managing chart dependencies through the Chart.yaml file is the more elegant solution it is sometimes not possible.

We mentioned that dependencies can be dropped in the charts directory. In fact, when we ran helm dependency update ./nginx all Helm did was download an archived MariaDB chart and drop it into that location.

Let’s move this out of our parent chart.

mv nginx/charts/* .

And extract the archive’s contents.

tar xzf mariadb*.tgz

The MariaDB chart will be extracted into the mariadb directory. This will serve its purpose for our next scenario.

We can imagine this is a chart we worked hard on. And now we want to include it as a dependency. To do that, all that is required is to move (or copy) it to the charts directory of our parent chart. But before we do that, let’s check the status of our Nginx chart.

helm template ./nginx

As expected, there is no MariaDB-related content anymore. Now, let’s move the MariaDB chart to our parent chart’s charts directory.

mv mariadb nginx/charts

Now, if we run helm template ./nginx again, we will see that the MariaDB chart is now included.

user@debian:~$ helm template ./nginx
---
# Source: nginx/charts/mariadb/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: RELEASE-NAME-mariadb
  namespace: default
  labels:
    app.kubernetes.io/name: mariadb
    helm.sh/chart: mariadb-9.3.16
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/managed-by: Helm
  annotations:
---
# Source: nginx/charts/mariadb/templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: RELEASE-NAME-mariadb
  namespace: default
  labels:
    app.kubernetes.io/name: mariadb
    helm.sh/chart: mariadb-9.3.16
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/managed-by: Helm
type: Opaque
data:
  mariadb-root-password: "Rm5jT2gwa2VBTQ=="
  mariadb-password: "VGVmVXRtak00RQ=="
---

Allowing the User to Switch Chart Dependencies On/Off

Like charts, dependencies can be smart, too, meaning they can adapt to the user’s needs instead of statically being included all the time, no matter what.

For example, a WordPress website can be sped up with Memcached. However, not all users will want to use Memcached for their own reasons. Maybe it doesn’t work well for their scenario, or it breaks something. In such cases, we can let our users control what dependency charts will be used and which won’t be used. In our case, we can make the use of Memcached optional by doing something like this in the Charts.yaml file.

dependencies:
  - name: mariadb
    repository: https://charts.bitnami.com/bitnami
    version: 9.x.x
  - name: memcached
    condition: memcached.enabled
    repository: https://charts.bitnami.com/bitnami
    version: 5.x.x

The line condition: memcached.enabled makes sure that the Memcached dependency chart will be used only if the user sets memcached.enabled to true in his values.yaml file.

Suppose we build the chart with the following content in the values.yaml file:

memcached:
  enabled: false

This makes sure that Memcached, by default, won’t be used.

This on/off feature gives the user a chance to enable it only if they manually set enabled: to true. This way, we don’t intrude on our user’s preferences. Instead, we allow them to enable optional content only if they want it.

Check out the Helm for the Absolute Beginners course.

Helm for Beginners | KodeKloud
Learn and get certified with simple and easy hands-on labs

Conclusion

Helm chart dependencies refer to other charts that the Helm chart relies on to function correctly. Prior to installing the primary chart, Helm will automatically download and install any necessary dependencies.

Users can choose which dependency charts to use by setting them as optional in Charts.yaml with a condition. This allows users to enable or disable dependencies based on their specific requirements.


More on Helm: