How to use Helmfile for managing helm chart?



Helmfile is an another wrapper working on top of Helm Chart. Just like Helm Chart, Helmfile also uses the YAML for writing the configurations.

But why do you need Helmfile if you are working with Kubernetes and Helm Chart?

Here are some key benfits of using Helmfile -

  1. You can bundle several Helm Charts into a Single Helmfile to manage your kubernetes eco system
  2. Helmfile helps you to keep isolation between the different environments(developemnt, staging, production)
  3. It can help you to identify the differences between the new changes which you want to apply against the existing running deployment inside kubernetes cluster
  4. Helmfile uses the Go Templates which lets you templatify your Helmfile and also you can use Sprig Library with functions - requiredEnv, exec, readFile, toYaml, fromYaml, setValueAtPath, get, tpl, required, fetchSecretValue, expandSecretRefs
  5. With the help of HelmFile you can deploy multi-tier applications inside kubernetes cluster.

This blog post will be a complete guide for anyone who want to learn Helfile for managing the HelmChart.

Table of Content -

  1. How to Install Helmfile and running docker container of helmfile
  2. Create your first Helmfile and install Helmchart
  3. Uninstall the helmchart using Helmfile
  4. Use GitHub repository for installing helm chart using Helmfile
  5. Deploy multiple Helmchart using Helmfile
  6. How to use Template and Environment variables insides Helmfile?
  7. Conclusion


1. How to Install Helmfile and running docker container of helmfile?

In this guide I am assuming that you have not used the Helmfile before so the first most appropriate step which I think would be to Installing Helmfile?

(Note :- But there is a prerequisite before installing the Helmfile, you must install the helmchart)

  1. Download the Helmfile from GitHub

  2. Rename the file from - helmfile_linux_amd64 to helmfile

1mv helmfile_linux_amd64 helmfile
  1. Change the permission of the file and make it executable
1chmod 777 helmfile 
  1. Move the file from current location to /usr/local/bin
1mv helmfile /usr/local/bin

5.After moving the file verify the Helmfile installation by running the command - $ helmfile –version


1.1 Running helmfile as a Docker container

If you like docker then you can spin up the docker image of the helmfile using the following docker run command.

1docker run --rm --net=host -v "${HOME}/.kube:/root/.kube"  \
2-v "${HOME}/.config/helm:/root/.config/helm"  \
3-v "${PWD}:/wd"  \
4--workdir /wd quay.io/roboll/helmfile:helm3-v0.135.0 helmfile sync 

2. Create your first Helmfile and install Helmchart

As we know Helmfile is just a wrapper on top of HelmChart, so after installing the Helmfile first we need to create a HelmChart

  1. Create a helloworld helmchart.
1helm create hellworld

  1. Let’s create a Helmfile for the helmchart we have just created and we are going to create helmfile.yaml at the same location where we have crated helloworld helmchart.

Here are the contents of helmfile.yaml-

1---
2releases:
3
4  - name: helloworld
5    chart: ./helloworld
6    installed: true 

installed: true - If you want to install the helmchart using helmfile then your must set this flag to true

  1. After creating the helloworld helmchart and its respective helmfile let’s try to install the helm chart by running the command $ helmfile sync
1helmfile sync 

After running the above command you should see the following output -

 1$ helmfile sync
 2Building dependency release=helloworld, chart=helloworld
 3Affected releases are:
 4  helloworld (helloworld) UPDATED
 5
 6Upgrading release=helloworld, chart=helloworld
 7Release "helloworld" does not exist. Installing it now.
 8NAME: helloworld
 9LAST DEPLOYED: Sun Oct 17 19:53:41 2021
10NAMESPACE: default
11STATUS: deployed
12REVISION: 1
13NOTES:
141. Get the application URL by running these commands:
15  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=helloworld,app.kubernetes.io/instance=helloworld" -o jsonpath="{.items[0].metadata.name}")
16  export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
17  echo "Visit http://127.0.0.1:8080 to use your application"
18  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
19
20Listing releases matching ^helloworld$
21helloworld	default  	1       	2021-10-17 19:53:41.44402394 +0000 UTC	deployed	helloworld-0.1.0	1.16.0
22
23UPDATED RELEASES:
24NAME         CHART        VERSION
25helloworld   helloworld     0.1.0 
  1. Verify the installation by running the command $ helm list -a
1helm list -a 
1NAME      	NAMESPACE	REVISION	UPDATED                               	STATUS  	CHART           	APP VERSION
2helloworld	default  	1       	2021-10-17 19:53:41.44402394 +0000 UTC	deployed	helloworld-0.1.0	1.16.0 

3. Uninstall the helmchart using Helmfile

In the previous step we have seen how to install the helmchart, now how about uninstalling the helmchart?

Well the uninstallation part is very simple when you are using the Helmfile. You simply need to set the flag installed: false

1---
2releases:
3
4  - name: helloworld
5    chart: ./helloworld
6    installed: false

After updating the helmfile you need to run the $ helmfile sync command again -

1helmfile sync  

4. Use GitHub repository for installing helm chart using Helmfile

The one more feature of Helmfile which I like the most is - you can even install the helmchart from remote repository such as GitHub, Google Container Repository, AWS ECR

Here is my GitHub repository for my helmchart - GitHub Helmchart Repo

Add the following configuration attributes for working with remote repository -

1. Repository name - helloworld

2. Repository URL - git+https://github.com/rahulwagh/helmchart@helloworld?ref=master&sparse=0

 1---
 2repositories:
 3  - name: helloworld
 4    url: git+https://github.com/rahulwagh/helmchart@helloworld?ref=master&sparse=0
 5
 6releases:
 7
 8  - name: helloworld
 9    chart: helloworld/helloworld
10    installed: false 

Now you can run the $ helmfile sync command for installing the helm chart from remote repository


5. Deploy multiple Helmcharts using Helmfile

Now we have seen in the previous steps how to deploy a local Helmchart as well as helmchart deployment from repository such as GitHub. In this section we will deploy multiple helmcharts using a Helmfile.

Use the following steps -

1. Create your first helm chart -

1helm create helloworld1

2. Create your second helm chart

1helm create helloworld2

3. Create a Helmfile for deploying multiple helmchart .i.e. helloworld1, helloworld2

 1---
 2releases:
 3
 4  - name: helloworld1
 5    chart: ./helloworld1
 6    installed: true
 7
 8  - name: helloworld2
 9    chart: ./helloworld2
10    installed: true

4. Install the helmchart using Helmfile

1helmfile sync  

5. After the successful deployment you should see following message onto your console

 1$ helmfile sync
 2Building dependency release=helloworld1, chart=helloworld1
 3Building dependency release=helloworld2, chart=helloworld2
 4Affected releases are:
 5  helloworld1 (helloworld1) UPDATED
 6  helloworld2 (helloworld2) UPDATED
 7
 8Upgrading release=helloworld1, chart=helloworld1
 9Upgrading release=helloworld2, chart=helloworld2
10Release "helloworld2" does not exist. Installing it now.
11NAME: helloworld2
12LAST DEPLOYED: Mon Oct 18 21:05:18 2021
13NAMESPACE: default
14STATUS: deployed
15REVISION: 1
16NOTES:

The same approach can be taken to deploy the multiple helmchart from GitHub repository also. You need to push all of your helmchart under single GitHub repository and add multiple number of releases configurations inside your helmfile. Here is an example of helmfile.yaml -

 1 ---
 2 repositories:
 3     - name: helloworld
 4       url: git+https://github.com/rahulwagh/helmchart@helloworld?ref=master&sparse=0
 5   
 6 releases:
 7
 8   - name: helloworld1
 9     chart: ./helloworld1
10     installed: true
11
12   - name: helloworld2
13     chart: ./helloworld2
14     installed: true

6. How to use Template and Environment variables insides Helmfile?

There is a really good support for template expressions as well as templated helm values. Inside the helmfile.yaml you can use values.yaml.gotmpl and it can explained simply by -

  1. .gotmpl - Any value files with .gotmpl extension will be rendered with template expressions.

  2. .yaml - File ending with .yaml extension will be used as plain value files

Here is example of value file template for helloworld helm chart-

1
2releases:
3- name: helloworld
4  chart: ./helloworld
5  values:
6  - values.yaml.gotmpl
7

In the above helmfile.yaml the value attribute which has an extension of .gotmpl will be treated as template file.

Let’s consider the values.yaml.gotmpl has following expression -

1{{ readFile "values.yaml" | fromYaml | setValueAtPath "foo.bar" "FOO_BAR" | toYaml }}

The above expression will be evaluated as -

1releases:
2- name: helloworld
3  chart: ./helloworld
4  values:
5  - foo:
6        bar: "FOO_BAR"

6.1 How to pass Environment values into helmfile.yaml

To easout the deployment process of test, stage and production, helmfile helps you to prepare the helmfile.yaml as well as values.yaml as per the environment.

You can create multiple environments(dev, test, stage, prod) inside the helmfile but keep in mind there exists one default environment which is always present.

Here is an example in which I have defined a test only environment -

1environments:
2  default:
3  test:
4---
5
6releases:
7   - name: helloworld1
8     chart: ./helloworld1
9     installed: true

Let us take one more example with default and production environment -

Here is my helmfile.yaml

 1
 2environments:
 3  production:
 4    values:
 5    - production.yaml
 6---
 7
 8releases:
 9   - name: helloworld1
10     chart: ./helloworld1
11     installed: true

And here is my values.yaml.gotmpl

1domain: {{ .Values | get "domain" "dev.example.com" }}

So if I run the $ helmfile sync command then it will use the value of domain = dev.example.com.

But let us define one more yaml named production.yaml and put following values in it -

1domain: prod.example.com
2releaseName: prod

Now re-run the $ helm –environment production sync. It will install the app with value domain = prod.example.com

6.2 Loading the environment values from remote

Along with passing the local environment values from local, helmfile also supports to pass the environment values from the remote github or any other repository such GCR, ECR etc.

Here is example of passing environment values remotely -

 1environments:
 2  cluster-azure-us-west:
 3    values:
 4      - git::https://github.com/rahulwagh/helmchart@helloworld?ref=master&sparse=0
 5
 6releases:
 7
 8  - name: helloworld1
 9    chart: ./helloworld1
10    installed: true

7.Conclusion

The helmfile is a must to have tool if you are managing your kubernetes infrastructure with HelmChart. Undoubtedly HelmChart brings in more advantages and feature when it comes to managing your kubernetes cluster but adding Helmfile will definitely help you with -

  1. Managing multiple helm charts with one single helmfile
  2. Isolating helmcharts as per the environment
  3. Identify the difference between the changes
  4. Improving your multi-tier kubernetes setup

Read More -

  1. Helm chart - How to Add/Install plugins
  2. Getting started with Helm Chart
  3. Helm chart - WordPress Installation with MariaDB on Kubernetes
  4. Helm chart - Build you first helm chart with Spring Boot
  5. Helm Chart - Convert Kubernetes YAML into Helm Chart YAML
  6. Helm Chart - Pass environment variables
  7. Helm Chart - Plugin
  8. Helm Chart - Dry Run Install
  9. Helm Chart - How to create multiple values files inside helm chart?
  10. Helmfile - How to use Helmfile for managing helm chart?