DEV Community

Cover image for Installing multiple helm charts in one go [Approach 3 - using simple bash utility]
Sunny Bhambhani for AWS Community Builders

Posted on • Edited on

Installing multiple helm charts in one go [Approach 3 - using simple bash utility]

In this article, we will be talking about Approach 3 i.e. how to get multiple helm charts installed using a simple bash utility.

If you haven't read the previous article where I discussed other approaches, feel free to read it over.

Motive

Why I thought of a simple bash utility?

  • In some of the air-gapped environments it is sometimes a bit difficult to use the tools/utilities available because moving things inside an air-gapped environment is a challenge.
  • Some of the environments are so secure that one may need to follow a whole process of getting all the security clearances and approval before using a tool/utility, which altogether is a nightmare.
  • I chose bash, the reason being it is pretty common among engineers and it is easily understandable.
  • The source code can be found here: https://github.com/sunnybhambhani/helmister
  • You can copy it, and tweak it based on your requirements.

PS: I chose a name for this utility as well helmister or helm-minister but you can call it whatever you want πŸ™‚

Prerequisites

  • A running Kubernetes cluster with proper permissions, it can be any flavor of Kubernetes minikube, Elastic Kubernetes Service(EKS), Azure Kubernetes Service(AKS), Google Kubernetes Engine(GKE), etc.
  • kubectl and helm installed on your machine to interact with the Kubernetes cluster.
  • A clone of helmister repository.
  • yq(required) and cowsay(optional) packages installed on your machine.

Helmister

  • This is a small bash utility that can help to install and uninstall multiple helm charts in one go. The idea is inspired by helmfile.
  • Its usage is quite simple, just run the utility followed by the option like install or uninstall i.e. ./helmister [install/uninstall].
  • Under the hood, it calls helm binary. Therefore it is kind of a wrapper around helm.
  • It consumes a config.yaml file which contains all the necessary details about the releases, and common parameters.
  • This supports both oci:// and https:// helm registries.
  • PS: In the future, I am planning to add some more options/functionalities to this.

Directory structure

. β”œβ”€β”€ config.yaml β”œβ”€β”€ helmister β”œβ”€β”€ logs β”‚ β”œβ”€β”€ archive β”‚ β”‚ └── helmister_20240227_170201.tar.gz β”‚ └── helmister.log β”œβ”€β”€ README.md └── values β”œβ”€β”€ argo-cd.yaml └── nginx-values.yaml 
Enter fullscreen mode Exit fullscreen mode
  • helmister, this is the script written in bash you can just cat and see what all things it contains.
  • config.yaml, this is the main configuration file or you can call the state file which contains the list of all releases you want to install in a cluster, plus it also contains some additional key:value pairs that are generic and common across all the releases. I first kept this configuration file in csv format, but later decided to convert it to yaml because it is more readable.
  • logs, this is a directory that holds the logs of this utility, it contains the information about the execution of the last iteration, plus any archived/past logs (if required for reference).
  • README.md, contains bit of a documentation about this utility, and what options are present.
  • values, this is the directory where all the values files are placed (it can be anywhere in your system but for simplicity, I have placed them in the same directory).
  • Now let's talk about config.yaml which is the main ingredient.

config.yaml

dry_run: false create_namespace: true wait: false timeout: false # If true, defaults to 20 mins charts: - release_name: nginx chart_name: nginx chart_repo: oci://registry-1.docker.io/bitnamicharts values_file: values/nginx-values.yaml - release_name: argocd chart_name: argo-cd chart_repo: https://argoproj.github.io/argo-helm values_file: values/argo-cd.yaml version: 6.4.0 namespace: argo-cd 
Enter fullscreen mode Exit fullscreen mode
  • The initial key:value pairs are common across all the releases.
  • charts, is an array that contains a list of what all releases need to be installed in a Kubernetes cluster.
  • dry_run, it is a boolean [true or false], and if true, none of the Kubernetes resources will be created it will just do a dry_run.
  • create_namespace, it is a boolean [true or false], and if true it will automatically create a namespace for the release specified in the charts array.
  • wait, it is a boolean [true or false], and if true it acts similar to helm --wait wherein the shell will be kept occupied until all the Kubernetes resources are created.
  • timeout, it is a boolean [true or false], and if true it acts similar to helm --timeout=20m i.e. if all the resources are not created within 20 mins the execution will fail. By default, I have kept the timeout as 20 minutes which is more than enough.
  • charts, it is an array that contains details around individual releases. Except for version and namespace all the key:value pairs are mandatory.
    • release_name, this is the name of the release.
    • chart_name, this is the name of the chart that needs to be installed.
    • chart_repo, this is the helm registry where the chart is located. It can be any oci:// or https:// registry.
    • values_file, which contains the path of the values file for individual releases.
    • version, this is the version of the chart that needs to be installed. This is optional and if not provided, It will consider the latest chart version.
    • namespace, this is where the chart will be installed. This is optional as well and if not provided it will be installed in the default namespace.

Let's see this in action

  • I will use the same config.yaml which will install one helm release from an oci:// registry in default namespace (since I haven't specified any namespace for that release) and another one from https:// registry in argo-cd namespace. Note the version as well for nginx, there as well I haven't specified any version, it will pick the latest available one automatically.
  • This is my cluster's current status.
$ k get ns NAME STATUS AGE default Active 28s kube-node-lease Active 28s kube-public Active 29s kube-system Active 29s 
Enter fullscreen mode Exit fullscreen mode
$ helm list -A NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION 
Enter fullscreen mode Exit fullscreen mode
$ ./helmister install [2024-07-23 15:02:47] [INFO] Using file: config.yaml ____________________________ < Helmister, Install charts! > ---------------------------- \ \ .--. |o_o | |:_/ | // \ \ (| | ) /'\_ _/`\ \___)=(___/ [2024-07-23 15:02:47] [INFO] Generic/common values based on config.yaml file [2024-07-23 15:02:48] [INFO] Dry Run: false [2024-07-23 15:02:48] [INFO] Create Namespace: true [2024-07-23 15:02:48] [INFO] Wait: false [2024-07-23 15:02:48] [INFO] Timeout: false [2024-07-23 15:02:48] [INFO] **************************** [2024-07-23 15:02:48] [INFO] Chart specific values based on config.yaml file [2024-07-23 15:02:48] [INFO] Release Name: nginx [2024-07-23 15:02:48] [INFO] Chart Name: nginx [2024-07-23 15:02:48] [INFO] Chart Repo: oci://registry-1.docker.io/bitnamicharts [2024-07-23 15:02:48] [INFO] Values File: values/nginx-values.yaml [2024-07-23 15:02:48] [INFO] Version: null [2024-07-23 15:02:48] [INFO] Namespace: null [2024-07-23 15:02:48] [INFO] **************************** [2024-07-23 15:02:48] [INFO] Installing nginx with release name nginx from oci://registry-1.docker.io/bitnamicharts with version null using values file: values/nginx-values.yaml in default namespace ... ... OUTPUT TRIMMED 
Enter fullscreen mode Exit fullscreen mode
  • Actual stdout output can be found here.
  • Here you will see that it provides all the minute details of what exactly it is doing.
  • For example: Generic values
    • Here I have marked create_namespace as true because I don't already have argo-cd namespace wherein I want to install argocd release.
[2024-07-23 15:02:47] [INFO] Generic/common values based on config.yaml file [2024-07-23 15:02:48] [INFO] Dry Run: false [2024-07-23 15:02:48] [INFO] Create Namespace: true [2024-07-23 15:02:48] [INFO] Wait: false [2024-07-23 15:02:48] [INFO] Timeout: false 
Enter fullscreen mode Exit fullscreen mode
  • Next, you will see, chart/release specific values of all the items in charts array one by one:
[2024-07-23 15:03:31] [INFO] Chart specific values based on config.yaml file [2024-07-23 15:03:31] [INFO] Release Name: argocd [2024-07-23 15:03:31] [INFO] Chart Name: argo-cd [2024-07-23 15:03:31] [INFO] Chart Repo: https://argoproj.github.io/argo-helm [2024-07-23 15:03:31] [INFO] Values File: values/argo-cd.yaml [2024-07-23 15:03:31] [INFO] Version: 6.4.0 [2024-07-23 15:03:31] [INFO] Namespace: argo-cd 
Enter fullscreen mode Exit fullscreen mode
  • Here I have explicitly added an additional check that will check if the pods are up and healthy (this is just specific to pods it won't consider any other k8s objects).
  • It will continuously check for next 20mins and will check every 5 secs. If the pods are still in non-running state it will terminate the process.
[2024-07-23 15:03:47] [WARN] Pods for release argocd are not yet in Running state, checking again in 5 seconds 
Enter fullscreen mode Exit fullscreen mode
  • Once all the pods are in running state and it has deployed all the releases it will show a successful message.
[2024-07-23 15:05:20] [INFO] All actions completed successfully 
Enter fullscreen mode Exit fullscreen mode
  • Once this is done, if required you can see the logs as well from the logs directory. A sample can be found here.
  • And here is my cluster's current status now:
$ helm list -A NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION argocd argo-cd 1 2024-07-23 15:03:34.46715742 +0530 IST deployed argo-cd-6.4.0 v2.10.1 nginx default 1 2024-07-23 15:02:53.590367521 +0530 IST deployed nginx-18.1.5 1.27.0 
Enter fullscreen mode Exit fullscreen mode
$ k get ns NAME STATUS AGE argo-cd Active 58m default Active 62m kube-node-lease Active 62m kube-public Active 62m kube-system Active 62m 
Enter fullscreen mode Exit fullscreen mode
$ k get pods -n argo-cd NAME READY STATUS RESTARTS AGE argocd-application-controller-0 1/1 Running 0 58m argocd-applicationset-controller-68cd75bc89-d4q8x 1/1 Running 0 58m argocd-dex-server-84b5bbdcbf-c4qv2 1/1 Running 0 58m argocd-notifications-controller-7bc55c495d-xz6gt 1/1 Running 0 58m argocd-redis-5d5cdcfd54-2rx26 1/1 Running 0 58m argocd-repo-server-756ff4cd7d-rpvh7 1/1 Running 0 58m argocd-server-7587d49b7b-9h47l 1/1 Running 0 58m 
Enter fullscreen mode Exit fullscreen mode
$ k get pods -n default NAME READY STATUS RESTARTS AGE nginx-569b6bc698-48qqt 1/1 Running 0 59m nginx-569b6bc698-9qzpv 1/1 Running 0 59m nginx-569b6bc698-wflrj 1/1 Running 0 59m 
Enter fullscreen mode Exit fullscreen mode
  • If you want to uninstall it, simply do:
$ ./helmister uninstall 
Enter fullscreen mode Exit fullscreen mode
  • It will get everything cleaned for all the releases that are specified in config.yaml.
  • The sample log can be found here.

Feel free to use it, and tweak it based on your requirements.

I will soon add some more functionalities to it.

Happy learning!

References:

  • Google/Stackoverflow/Linux man pages/etc

Top comments (5)

Collapse
 
zhilyaev profile image
Dmitriy Zhilyaev

Try docs.helmwave.app/ go executive for helm charts

Collapse
 
sunnybhambhani profile image
Sunny Bhambhani AWS Community Builders

Sure, I will give it a try.

Collapse
 
sunnybhambhani profile image
Sunny Bhambhani AWS Community Builders
Collapse
 
sunnybhambhani profile image
Sunny Bhambhani AWS Community Builders
Collapse
 
sunnybhambhani profile image
Sunny Bhambhani AWS Community Builders