Skip to content

Instantly share code, notes, and snippets.

@DWSR
Created November 22, 2022 17:01
Show Gist options
  • Save DWSR/a2880d698329663375d760bb3fc49aff to your computer and use it in GitHub Desktop.
Save DWSR/a2880d698329663375d760bb3fc49aff to your computer and use it in GitHub Desktop.
For the love of all things sacred, please stop using Helm

Helm attempts to solve a specific problem: How do you package up a bunch of Kubernetes manifests in a way that's (relatively) easy to consume.

For simple applications, this works out pretty well. You get a few knobs to tweak on the installation (such as whether or not you want the Chart to create RBAC resources), Helm renders a stream of YAML and then applies it to your cluster. Where this breaks down is when you try to do anything more complex, and that break down happens in 2 areas: Maintenance and Usability

Sufficiently complex (read: any) Helm charts can be thought of as a piece of software. It takes a series of inputs (the values) and produces a series of outputs (the YAML stream of Kubernetes objects). With "traditional" languages, there's facilities for syntax checking, static analysis, testing, etc. that help ensure the software both functions correctly now and in the future. The Helm ecosystem has some of those same things (e.g. helm lint) as well, however they're generally limited to treating the Helm chart as a black box. The reason for this is that Helm templates are actually just text templates using gotpl and Sprig, similar to how Ansible uses Jinja2. The result is a file that is entirely naive to the data structure it contains, meaning authors need to start being mindful of syntax concerns like indentation, or they start stubbing out entire templates to try and ease maintenance burden. This is nothing short of madness.

Instead, project maintainers should look to tools like CDK8s, naml, or writing a Kubernetes Operator via a framework like kubebuilder. Using any of these projects shifts the authoring process from "writing a bunch of text templates" to "writing code" and enables the use of "regular" coding practices and patterns. For example, kubebuilder provides a testing harness that spins up a Kubernetes API server for your operator to run against so that you can test how it reacts to changes in the cluster.

The usability of Helm charts is also hugely problematic for all but the simplest cases. For example, what happens if the Helm chart bundles a PodSecurityPolicy but you're now on Kubernetes 1.25 where PSPs have been removed? Or the Helm chart doesn't allow you to set labels for a Deployment's pods? Or it forcibly generates a ServiceAccount and doesn't allow you to use an existing one. Or, the most common stumbling block: The only way to supply secrets to the Chart is via values.yaml, which totally clashes with your current secret management processes. The more complex your use case (e.g. because of security and compliance), the more you're going to be struggling against the Chart author's opinions. In many cases, you can at least mitigate some of these issues by wrapping tooling around Helm (such as Kustomize) and using the wrapper for "last mile" patching. However, this doesn't work in every case and undoubtedly you will find yourself forking the upstream chart to do something frivolous like ensuring the Chart actually renders valid YAML.

Finally, Helm itself has usability problems, namely around installations, rollbacks, and hooks. Any use of these features will undoubtedly have a horror story about a time when Helm was wedged because of a failing Hook or a rollback ate their mission-critical app. These operations often require some level of orchestration between various components. Authors will often try to use hooks as a way to achieve that orchestration, but this leads to brittle, fragile charts where the experience of upgrading and installing the chart is more frustrating and time consuming that operating the software that the chart was supposed to install.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment