Helmfile: What Is It?

Paul Czarkowski

Helmfile adds additional functionality to Helm by wrapping it in a declarative spec that allows you to compose several charts together to create a comprehensive deployment artifact for anything from a single application to your entire infrastructure stack.

Note: If you’re not familiar with Helm, start with our Getting Started with Helm guide.

In addition to the Templating and Packaging Helm gives you for your Kubernetes manifests, Helmfile provides a way to apply GitOps style CI/CD methodologies over your Helm charts by:

  • Separating out your Environment specific information from your Chart
  • Performing a diff of your existing deployment and only applying the changes

Helmfile uses the same templating system as Helm and in a way lets you template your templates (). This can be a bit difficult to wrap your mind around at first, but adds a ton of powerful features as it allows you to put basic programming logic like if/then/else into just about any component including your actual Helm Chart Values.

Why Is It Important?

Helm is a great tool for templating and sharing Kubernetes manifests for your applications. However it can become quite cumbersome to install larger multi-tier applications or groups of applications across multiple Kubernetes clusters.

Helmfile addresses this issue and more by providing a fairly simple but very powerful declarative specification for deploying Helm charts across many environments.

First and foremost Helm is a declarative specification. Like Kubernetes manifests you can store them in version control, and perform declarative style actions. Much like Kubernetes has kubectl apply for Kubernetes manifests, Helmfile has helmfile apply for Helm charts.

Helmfile is very modular, you can have one large helmfile.yaml that does everything or you can break it down to suit your way of working. This modularity allows you to:

  • Give each Helm chart its own helmfile.yaml and include them recursively in a centralized helmfile.yaml.

  • Separate out environment specific values from general values. Often you’ll find while a Helm chart can take 50 different values, only a few actually differ between your environments.

  • As well as providing a set of values, either Environment specific or otherwise, you can also read Environment Variables, Execute scripts and read their output.

  • Store remote state in git/s3/fileshare/etc in much the same way as Terraform does.

Helmfile is versatile enough to allow you to also include raw Kubernetes manifests, Kustomizations, or even execute scripts via hooks, turning all of these into Helm releases.

Need to modify the resources generated by a specific Helm chart? Helmfile allows you to JSON/Strategic-Merge patch resources before actually installing them.

How Does It Work?

Helmfile works by reading in your Helmfile manifest (usually helmfile.yaml) which declares the Helm Charts you want to install and the values you wish to install them with, these are compared against the actual state of what is running in your cluster and any differences are then acted upon by calling out to Helm itself.

A basic helmfile.yaml to install nginx would look something like this:

./apps/nginx/helmfile.yaml

repositories:
  - name: stable
    url: https://kubernetes-charts.storage.googleapis.com

releases:
  - name: my-nginx-server
    namespace: default
    labels:
      app: nginx
    chart: stable/nginx
    version: ~1.24.1
    values:
      - ./nginx/vault.yaml.gotmpl
      - image: my.registry.com/nginx

Values are a list that can be passed in as a file or a list of key/values. These are the helm style values that will be rendered into your chart. Helmfile will treat any file with the .gotmpl extension as a template and will render it before passing it onto Helm.

If you wanted to load the above into a parent helmfile.yaml you could do the following:

./helmfile.yaml

helmfiles:
  - apps/*/helmfile.yaml

You can even make all of your included helmfile.yaml files templates and render stuff right into the helmfiles. It really is templates all the way down.

./helmfile.yaml

helmfiles:
  - apps/*/helmfile.yaml.gotmpl

Thankfully the Helmfile GitHub repository has some really good documentation and best practices showing different ways to construct your helmfile.yaml files.

How Can I Use It?

It’s pretty easy to get started with Helmfile. The documentation in the repository is quite good.

For an interesting perspective showing how to completely decouple your Code and Environment data have a look at Paul Czarkowski’s Helmfile Starter Kit and the Platform Operations on Kubernetes project built on top of it. The latter of which is used to deploy a whole kitchen sink worth of platform tooling across dozens of Kubernetes clusters.