DEV Community

Cover image for Installing multiple helm charts in one go [Approach 1 - using parent/child charts]
Sunny Bhambhani for AWS Community Builders

Posted on • Edited on • Originally published at cncf.io

Installing multiple helm charts in one go [Approach 1 - using parent/child charts]

Helm is really a very powerful tool for managing Kubernetes objects and is widely adopted across various organizations. It is truly a game changer on how Kubernetes objects are being managed.

With a single command, we can install or upgrade multiple related Kubernetes entities together, we need not to worry about how the resources will be created, Helm will do all the heavy lifting for us.

$ helm install [RELEASE_NAME] [REPO]/[CHART]
Enter fullscreen mode Exit fullscreen mode

But the below post is not about the basics of helm or how to install or upgrade a chart, etc. It's about some new ways of getting charts deployed.

Let's say you have a requirement for getting more than 100 charts installed on a specific Kubernetes cluster, what would you do in this scenario?

On top of my head, I can think of a couple of approaches:

Prerequisites:

Approach 1:

Club inter-related charts into one, as in getting a parent/wrapper chart created which will in turn have the related child charts as dependency. Which mean if we install the parent/wrapper chart it will get all the Kubernetes resources of all the child charts deployed (provided they are marked as enabled in Chart.yaml).

Below is a quick example, wherein I have a 3-Tier application named app01.

  • If you notice the output of both the commands in the parent's Chart.yaml I have all three charts listed as dependencies and in the other one, individual charts have their own Kubernetes resources.
$ cat Chart.yaml
apiVersion: v2
name: app01
description: A Helm chart for app01 which contains FE, BE, DB.
version: 0.1.0
appVersion: 1.0.0
dependencies:
  - name: webapp
    version: "0.1.0"
    repository: "file://./charts/webapp"
    enabled: true
  - name: backend
    version: "0.1.0"
    repository: "file://./charts/backend"
    enabled: true
  - name: database
    version: "0.1.0"
    repository: "file://./charts/database"
    enabled: true
Enter fullscreen mode Exit fullscreen mode
$ tree
.
├── Chart.yaml
├── charts
│   ├── backend
│   │   ├── Chart.yaml
│   │   ├── charts
│   │   ├── templates
│   │   │   ├── _helpers.tpl
│   │   │   ├── deployment.yaml
│   │   │   ├── hpa.yaml
│   │   │   ├── ingress.yaml
│   │   │   ├── service.yaml
│   │   │   └── serviceaccount.yaml
│   │   └── values.yaml
│   ├── database
│   │   ├── Chart.yaml
│   │   ├── charts
│   │   ├── templates
│   │   │   ├── _helpers.tpl
│   │   │   ├── deployment.yaml
│   │   │   ├── hpa.yaml
│   │   │   ├── ingress.yaml
│   │   │   ├── service.yaml
│   │   │   └── serviceaccount.yaml
│   │   └── values.yaml
│   └── webapp
│       ├── Chart.yaml
│       ├── charts
│       ├── templates
│       │   ├── _helpers.tpl
│       │   ├── deployment.yaml
│       │   ├── hpa.yaml
│       │   ├── ingress.yaml
│       │   ├── service.yaml
│       │   └── serviceaccount.yaml
│       └── values.yaml
└── values.yaml

10 directories, 26 files
Enter fullscreen mode Exit fullscreen mode
  • When we install the parent chart it will get all the Kubernetes resources deployed.
$ helm install app01 ./app01/
NAME: app01
LAST DEPLOYED: Sat Dec  2 00:14:50 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
Enter fullscreen mode Exit fullscreen mode
$ helm list -A
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
app01   default         1               2023-12-02 00:14:50.075444065 +0530 IST deployed        app01-0.1.0     1.0.0
Enter fullscreen mode Exit fullscreen mode
$ k get all
NAME                                  READY   STATUS    RESTARTS   AGE
pod/app01-backend-965cb9b5b-q7gqv     1/1     Running   0          17m
pod/app01-database-56bdbcd49c-bh4s2   1/1     Running   0          17m
pod/app01-webapp-5b67db8bdf-m6psg     1/1     Running   0          17m

NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/app01-backend    ClusterIP   10.107.53.8      <none>        8080/TCP  17m
service/app01-database   ClusterIP   10.104.173.124   <none>        3306/TCP  17m
service/app01-webapp     ClusterIP   10.111.168.18    <none>        80/TCP    17m
service/kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP   8d

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/app01-backend    1/1     1            1           17m
deployment.apps/app01-database   1/1     1            1           17m
deployment.apps/app01-webapp     1/1     1            1           17m

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/app01-backend-965cb9b5b     1         1         1       17m
replicaset.apps/app01-database-56bdbcd49c   1         1         1       17m
replicaset.apps/app01-webapp-5b67db8bdf     1         1         1       17m
Enter fullscreen mode Exit fullscreen mode
  • Another thing to note here is now we have 4 values.yaml files (one for each child chart and one for the parent helm chart).
  • And the good part here is using just one parent's values.yaml file we can manage all 3 of them.
  • Make sure in parent's values.yaml, the child chart's values are indented correctly, and they are indented under specific chart name as mentioned in Chart.yaml under .dependencies[*].name
$ cat values.yaml
webapp:
  replicaCount: 2

database:
  replicaCount: 1

backend:
  replicaCount: 3
Enter fullscreen mode Exit fullscreen mode
  • Here we are just updating the replicaCount of all child charts and are upgrading the release.
$ helm upgrade --install app01 ./app01/
Release "app01" has been upgraded. Happy Helming!
NAME: app01
LAST DEPLOYED: Sat Dec  2 01:21:56 2023
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
Enter fullscreen mode Exit fullscreen mode
  • As specified in parent chart values.yaml, the replicaCount is now increased to 2,3 respectively.
$ k get deploy; k get pods
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
app01-backend    3/3     3            3           105m
app01-database   1/1     1            1           105m
app01-webapp     2/2     2            2           105m
NAME                              READY   STATUS    RESTARTS   AGE
app01-backend-965cb9b5b-dg6gq     1/1     Running   0          38m
app01-backend-965cb9b5b-q7gqv     1/1     Running   0          105m
app01-backend-965cb9b5b-z92c8     1/1     Running   0          38m
app01-database-56bdbcd49c-bh4s2   1/1     Running   0          105m
app01-webapp-5b67db8bdf-c25kc     1/1     Running   0          38m
app01-webapp-5b67db8bdf-m6psg     1/1     Running   0          105m
Enter fullscreen mode Exit fullscreen mode
  • As you see here with a single command, we deployed multiple helm charts and using a single values.yaml file we have the ability to manage all of them.

Approach 2:

Using helmfile.

Approach 3:

Using bash or any other scripting language (I am planning to write a simple utility to accomplish this).

Further, I am in the process of writing another article around Approach 2 and 3, plus there can be multiple other approaches for getting this accomplished (feel free to share your thoughts and comments).

Happy learning :)

PS: The cover image is created using canva.

Top comments (4)

Collapse
 
sunnybhambhani profile image
Sunny Bhambhani
Collapse
 
sunnybhambhani profile image
Sunny Bhambhani
Collapse
 
oracion profile image
mikhael andrew

For the Chart.yaml inside the dependencies, do I need to specify the dependency too? e.g. in backend's Chart.yaml, dependencies is database and frontend

Collapse
 
sadeek_ profile image
SadeekM

nice article