helmfile — it’s like a helm for your helm!

Hi,

So at Transit we’ve been migrating our workloads to GKE. Naturally, we’ve been using helm to package them.

Until recently, we had a pretty OK bash script to install desired releases to various clusters, but wanted a more declarative (and readable!) approach.

My buddy (and CNCF ambassador extraordinaire) Archy told me about helmfile so we checked it out and a few hours of YAML later our bash script was history and we were using helmfile in production to manage all our releases.

Let’s take a look at what works for us.

Environments

environments:
production:
staging:
test:

Helmfile structure

We went with the approach of having a helmfile.d directory with multiple helmfiles in it, each representing a namespace:

helmfile.d/
├── default.yaml
├── logging.yaml
├── monitoring.yaml
├── rt-data.yaml
├── sqlproxy.yaml
└── tracing.yaml

We will take a look at what one of these looks like, but first check out the values files structure.

Values

values
├── default
│ └── my-nginx-ingress-release
│ ├── test.yaml
│ ├── production.yaml
│ └── staging.yaml
├── logging
│ ├── my-elasticsearch-release
│ │ ├── test.yaml
│ │ ├── production.yaml
│ │ └── staging.yaml
│ └── my-kibana-release
│ ├── test.yaml
│ ├── production.yaml
│ └── staging.yaml
├── monitoring
│ ├── my-grafana-release
│ │ ├── production.yaml
│ │ └── staging.yaml
│ ├── my-prometheus-release
│ │ ├── production.yaml
│ │ └── staging.yaml
│ └── my-prometheus-operator-release
│ └── test.yaml
├── rt-data
│ └── my-rt-server-release
│ ├── test.yaml
│ ├── production.yaml
│ └── staging.yaml
├── sqlproxy
│ └── my-gcloud-sqlproxy-release
│ ├── test.yaml
│ ├── production.yaml
│ └── staging.yaml
└── tracing
└── my-jaeger-release
├── test.yaml
├── production.yaml
└── staging.yaml

Ok great. So now there was something to consider, we did not want every release installed in every environment (notice the values files in the monitoring namespace).

What release goes where

templates:
monitoring: &monitoring
chart: stable/{{`{{ .Release.Name }}`}}
missingFileHandler: Error
namespace: monitoring
values:
- ../values/monitoring/{{`{{ .Release.Name }}`}}/{{`{{ .Environment.Name }}`}}.yaml
releases:- name: my-grafana-release
installed: {{ eq .Environment.Name "staging" "production" }}
<<: *monitoring
- name: my-prometheus-release
installed: {{ eq .Environment.Name "staging" "production" }}
<<: *monitoring
- name: my-prometheus-operator-release
installed: {{ eq .Environment.Name "test" }}
<<: *monitoring

Notice the use of Go templating for the value of installed? Pretty sweet!

Conclusion

So if you are looking for a helm for your helm, swing by https://github.com/roboll/helmfile

DevOps @ Transit

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store