Aug 4, 2020

Managing your Helm deployments with Helmfile

As we’ve been using Kubernetes to build software delivery platforms for our clients, we’ve found Helm to be a reasonable solution to templating and managing deployments to Kubernetes. 

Although templating alternatives such as Kustomize have been gaining popularity, Helm still offers some advantages – notably, a large collection of publicly-available charts for common applications.

As you get started with Helm, often the tutorials have you working with imperative commands, e.g.:

$ helm install my-release ./my-chart

$ helm upgrade my-release ./my-chart

Notice the difficulties we would have here in developing a CD pipeline around this. First, the command differs from the first deployment, to the second deployment. Thankfully, Helm offers an easy way around this:

$ helm upgrade --install my-release ./my-chart

The --install flag will install the release if it has not already been installed.

What to do about values, however?

$ helm upgrade my-release ./my-chart set labelValue=something

helm upgrade … set passes a value into the Helm chart. That value is then persisted and used in future upgrades, even if you don’t use “set”. That wouldn’t work very well in a CI pipeline. Again, Helm has a solution for this:

$ helm upgrade --install my-release ./my-chart --values dev.yaml

When developing a CD pipeline around Kubernetes deployments, we found that every pipeline looked pretty much the same, just different names, and different values. Rather than require each repository to duplicate pipeline logic, we were looking for a declarative (configuration-driven) solution to define desired Helm releases, versions, and values. Enter Helmfile.

Helmfile is a simple wrapper around Helm. You simple add a simple helmfile.yaml file and run helmfile sync — Helmfile will determine whether an install or upgrade is necessary, compile the values, and run Helm.

# helmfile.yaml

releases:
- name: my-release
  chart: ./my-awesome-chart
  values:
  - dev.yaml


It’s a very straightforward tool, but it scratches an itch we had! It also supports a number of other features:

1. Hemfile supports Go templating in values files and helmfile.yaml, so you can look up values at deploy time (e.g., grab a value from a Terraform output or pull from environment)

# helmfile.yaml

{{ $environment := env "ENVIRONMENT" | default "dev" }}
releases:
- name: my-release
chart: ./my-awesome-chart
values:
- {{ $environment }}.yaml

2. You can make uninstalls declarative, in a sense with “installed: false”

# helmfile.yaml

releases:
- name: my-release
  chart: ./my-awesome-chart
  installed: false
  values:
  - {{ $environment }}.yaml


2. Many Helm flags can be specified via the config file, such as “—wait”, “–history-max”, etc.

# helmfile.yaml

helmDefaults:
  wait: true
  historyMax: 3

releases:
- name: my-release
  chart: ./my-awesome-chart
  values:
  - {{ $environment }}.yaml

3. You can specify multiple releases in a single Helmfile:

# helmfile.yaml

# oh yeah, and dynamically specify repositories!
repositories:
- name: bitnami
  url: https://charts.bitnami.com/bitnami

releases:
- name: my-release
  chart: ./my-awesome-chart
  values:
  - {{ $environment }}.yaml
- name: postgres
  chart: bitnami/postgresql
  values:
  - postgres-{{ $environment }}.yaml

4. You can preview the rendered chart output with “helmfile template”.

$ ENVIRONMENT=production helmfile template
Building dependency release=my-release, chart=my-awesome-chart
Templating release=my-release, chart=my-awesome-chart
---
# Source: my-awesome-chart/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: me
  labels:
    foo: dev


There are so many more ways to use Helmfile! We’ve been using it successfully for a few years now and it has remained under active development. Need help making your Kubernetes platform production-ready? Reach out!

About the Author

Object Partners profile.
Leave a Reply

Your email address will not be published.

Related Blog Posts
Building Better Data Visualization Experiences: Part 1 of 2
Through direct experience with data scientists, business analysts, lab technicians, as well as other UX professionals, I have found that we need a better understanding of the people who will be using our data visualization products in order to build them. Creating a product utilizing data with the goal of providing insight is fundamentally different from a typical user-centric web experience, although traditional UX process methods can help.
Kafka Schema Evolution With Java Spring Boot and Protobuf
In this blog I will be demonstrating Kafka schema evolution with Java, Spring Boot and Protobuf.  This app is for tutorial purposes, so there will be instances where a refactor could happen. I tried to […]
Redis Bitmaps: Storing state in small places
Redis is a popular open source in-memory data store that supports all kinds of abstract data structures. In this post and in an accompanying example Java project, I am going to explore two great use […]
Let’s build a WordPress & Kernel updated AMI with Packer
First, let’s start with What is an AMI? An Amazon Machine Image (AMI) is a master image for the creation of virtual servers in an AWS environment. The machine images are like templates that are configured with […]