New Wave for Helm!

Maria Kotlyarevskaya
Wrike TechClub
Published in
5 min readMar 15, 2022

--

There are an endless number of tools to deploy to Kubernetes, but a new tool may be the only one you need.

Landscape from CNCF website with application definition and CI/CD tools.

Quick recap

I’ve been using helmfile for a long time as a single solution for declaratives deployments to Kubernetes.

I’ve shared my thoughts about some of its feature in a separate article.

It has a bunch of features that I like, including:

  • Built-in templates
  • Environments with default option
  • Support of helm diff plugin
  • Integration with Vault

But I’m always looking for something new. Another tool may be easier to use, or it could resolve the problem in a better way. This is where helmwave comes in.

What is helmwave?

From the project’s readme on Github:

🌊 Helmwave is like docker-compose for @helm

In other words, helmwave is another tool to deploy helm-charts. Why is it better than the competitors though? Let’s dive in!

What are some of helmwave’s features?

Besides the standard features, like everything as a code, multi-environment deployments, and the ability to configure common values, it has some interesting functionalities:

  • Step-by-step deployment (depends_on, allow_failure)
  • Live tracking Kubernetes resources with kubedog
  • No requirements (you only need to download one binary for helmwave and you’re good to go!)
Comparison to alternatives from helmwave documentation

Example of how to use helmwave

I decided to solve a common issue — configuring deployment to several environments from one place with ability to overwrite configuration.

First of all, we need to take a look at the project structure.

.
├── .github/
├── .kube-linter
│ └── config.yaml
├── README.md
├── charts
│ ├── adservice
│ ...
│ └── shippingservice
├── envs-values
│ ├── prod
│ └── stage
├── helmwave.yml
├── helmwave.yml.tpl
└── releases.yaml
  • .github/ contains CI/CD configuration
  • .kube-linter/ contains configuration file for one of the Kubernetes manifests linter
  • charts/ contains helm-charts for microservices-demo app
  • envs-values/ contains values for stage and production environments
  • helmwave.yml is a rendered file from template: helmwave.yml.tpl
  • helmwave.yml.tpl is a template file for deployment configuration
  • releases.yaml is a file with list of apps and their configuration to be deployed

helmwave.yml.tpl

On top of this file, we have a version of helmwave tool. The latest is 0.18.0.

Below, we can configure an anchor that we can paste whenever we need to in the releases section. Usually, you’ll want to specify some defaults here, like namespace, helm options, etc. A full list of parameters is available here.

In the releases section, we define a list of helm releases to be deployed. To do so, we read the releases.yaml file and get the releases list. Each release should have a name and a chart from where it should be deployed. Other parameters are optional.

In my example it will also:

  • Add values for specific environment which is controlled by environment variable: CI_ENVIRONMENT_NAME
  • Add a tag with the name of application that we can use to deploy specific services not the whole list
  • Add parameters from the options anchor via <<: *options.

releases.yaml

File releases.yaml has a self-explanatory structure:

helmwave.yml

To generate the final helmwave configuration file (helmwave.yml), we can execute the following command:

CI_ENVIRONMENT_NAME=stage helmwave yml

It produces the following output:

Deployment workflow

For implementation of CI/CD processes, I chose Github Actions, as it’s built-in in Github and helmwave’s team provides a Github Action to manage installation of various helmwave’s versions.

The process consists of three steps: preparation, running the tests and run deployment to the correspondent environment.

CI/CD workflow

In the preparation stage, we install the required tools — helmwave and kind (this creates a Kubernetes cluster using containers) — define the environment, and prepare a plan of changes.

To define the environment, you can use bash script and pass the result to the next steps.

For testing and linting our application, we need to generate raw Kubernetes manifests, then they will be deployed to the target environment. For that, you can run one of these commands:

# if you have already ran helmwave yml
helmwave build
# generate helmwave.yml and manifests all at once
helmwave build --yml

These commands produce the .helmwave directory that contains the required manifests. You can run them locally to verify the result.

For testing, I use the most popular tools:

They are similar in some ways but each tool has different interesting features, so I decided to use all three in one pipeline.

For the deployment step, you can use the same command for generating a plan of changes. But if you deploy to a temporary environment (which is my case), you need to pass an additional parameter — diff-mode=local — which tells it to render diff locally without querying the Kubernetes cluster.

helmwave build --yml --diff-mode=local

To deploy the application, run the following command with the option kubedog if you want to see the progress of the deployment process.

helmwave up --kubedog# or all at once
helmwave up --yml --build --kubedog

Clean up

To delete all the deployed resources, you can run:

helmwave down# or delete kubernetes namespace
kubectl delete microservices-demo
Full demo

Conclusion

Helmwave is a full-featured alternative for helmfile and similar tools. It already has a number of interesting capabilities and I’m looking forward to see how the project develops.

I would recommend using it when you want to easily set up deployment without any external dependencies, quickly integrate it to some CD system and deliver your application to the customers.

Useful links

  1. Repository with all code and configuration is available here: https://github.com/Jasstkn/helmwave-demo
  2. Helmwave documentation: https://helmwave.github.io/
  3. Helmwave on Github: https://github.com/helmwave/helmwave/

--

--