After some work with kubernetes, i must really say, helm is a complexity hell. I'm sure it has much features but many aren't needed but increase the complexity nonetheless.
Also, please fix the "default" helm chart template, it's a nightmare of options and values no beginner understands. Make it basic and simple.
Nowadays i would very much prefer to just use terraform for kubernetes deployments, especially if you use terraform anyway!
Incidentally, Terraform is the only way I want to use Helm at all. Although the Terraform provider for Helm is quite cumbersome to use when you need to set values.
I've embraced kustomize and I like it. It's simple enough and powerful enough for my needs. A bit verbose to type out all the manifests, but I can live with it.
I only whish terraform was more recognized by upstream projects, like postgres, tailscale, ingress operators.
A one-time adoption from kubectl yaml or helm to terraform is doable - but syncing upstream updates is a chore.
If terraform (or another rich format) was popular as source of truth - then perhaps helm and kubectl yaml could be built from a terraform definition, with benefits like variable documentation, validation etc.
Helm is truly a fractal of design pain. Even the description as a "package manager" is a verifiable lie - it's a config management tool at best.
Any tool that encourages templating on top of YAML, in a way that prevents the use of tools like yamllint on them, is a bad tool. Ansible learned this lesson much earlier and changed syntax of playbooks so that their YAML passes lint.
Additionally, K8s core developers don't like it and keep inventing things like Kustomize and similar that have better designs.
Helm, and a lot of devops tooling, is fundamentally broken.
The core problem is that it is a templating language and not a fully functional programming language, or at least a DSL.
This leads us to the mess we are in today. Here is a fun experiment: Go open 10 helm charts, and compare the differences between them. You will find they have the same copy-paste bullshit everywhere.
Helm simply does not provide powerful enough tools to develop proper abstractions. This leads to massive sprawl when defining our infrastructure. This leads to the DevOps nightmare we have all found ourselves in.
I have developed complex systems in Pulumi and other CDKs: 99% of the text just GOES AWAY and everything is way more legible.
You are not going to create a robust solution with a weak templating language. You are just going to create more and more sprawl.
Maybe the answer is a CDK that outputs helm charts.
Imagine 1,000s of helm charts. Your only abstraction tools are an umbrella chart or a library chart. There isn't much more in helm.
I liked KRO's model a lot but stringly typed text templating at the scale of thousands of services doesn't work, it's not fun when you need to make a change. I kinda like jsonnet plus the google cli i forget the name of right now, and the abstraction the Grafana folks did too but ultimately i decided to roll my own thing and leaned heavily into type safety for this. It's ideal. With any luck i can open source it. There's a few similar ideas floating around now - Scala Yaga is one.
I've used it in the past (for a quite small deployment I must say), but have been very happy with it. Specifically the diff mode is very powerful to see what changes you'll apply compared to what's currently deployed.
Yes, I currently have 2 timoni modules in production, deployed with ArgoCD - and it's great! It has a bit of a learning curve and takes a bit of getting used to, that there is no "overwriting" values, but it saves so much time on template iteration.
The language server support for cue could be better, though.
I wrote Go and Python programs that constructed the manifests using the native Kubernetes types and piped them into kubectl apply. Had to write my own libraries for doing migrations too. But after that bootstrapping it worked great.
Kubernetes API uses JSON. JSON is JavaScript Object Notation. So naturally the best approach to work with JSON is to write JavaScript or TypeScript code. You can just output JSON and consume it with kubectl. You can read data from whatever format you want, process it and output JSON. You can write your little functions to reduce boilerplate. There are many options that are obvious once you just embrace JavaScript.
Of course most other programming languages will work just as well, it's just JavaScript being the most natural fit for JSON.
> Kubernetes API uses JSON. JSON is JavaScript Object Notation. So naturally the best approach to work with JSON is to write JavaScript or TypeScript code.
I don't really like this superficial reasoning. You can specify, generate, parse, and validate JSON in many common languages with similar levels of effort.
Saying you should use JavaScript to work with JSON because it has JavaScript in the acronym is about as relevant as comparing Java to JavaScript because both have Java in the name.
But really any kind of reconciler, e.g. flux or argo with helm works very well. Helm is only used as a templating tool, i.e. helm template is the only thing allowed. It works very well and I've ran production systems for years without major issues.
I dont really understand how people have so much trouble with Helm, granted yaml whitespace + go templating is sometimes awful, it is the least bad tool out there that I have tried and once you learn the arcane ways of {{- its mostly a non-issue.
I would recommend writing your own charts for the most part and using external charts when they are simple, or well proven. Most applications you want to run arent that complicated, they are mostly a collection of environment variables, config files, and arguments.
If I could wish for a replacement of helm, it would be helm template with the chart implemented in a typed language, e.g. TypeScript, instead of go template but backwards compatible with go template.
Im quite happy with FluxCD+Helm. Helm also supports creating library charts (basically component libraries) that can improve the experience of creating and maintaining helm charts by a lot.
Terraform. It’s declarative, type safe and just expressive enough to create basic conditionals, loops and reusable modules. Providers exists for all clouds and k8s.
Now it’s not perfect either. It does have some issues with slow querying of the current state during planning, even when it has the tfstate as a cache, which is another source of errors.
terraform with helm/kubernetes/kubectl providers is hit or miss. But I love it for simple things. For hairy things I will want full TypeScript with Pulumi.
> Update any automation that uses these renamed CLI flags.
I wish software providers like this would realize how fucking obnoxious this is. Why not support both? Seriously, leave the old, create a new one. Why put this burden on your users?
It doesn't sound like a big deal but in practice it's often a massive pain in the ass.
Came here to feel the temperature of the comments, and unsurprisingly, most folks seem to have plenty of gripes with Helm.
A Helm chart is often a poorly documented abstraction layer which often makes it impossible to relate back the managed application's original documentation to the Helm chart's "interface". The number of times I had to grep through the templates to figure out how to access a specific setting ...
I don't understand why having to "grep through the templates" is so bad. Oh, I get it, you just want to know what knobs are available for tweaking, and in a well-designed chart those will all be segregated in values files, with overrides specified on the command-line as needed. And so that's what documentation is for, and if a chart does not surface certain knobs from the product, well, yeah, you'll have to modify the chart if you want it to.
What is the essence of the complaint here? That chart authors do poor jobs? That YAML sucks (it does! it so so does!)? Just that charting provides an abstraction you'd rather not have? (If so, why not just... not use Helm?) Something else?
As said, that I often cannot relate the managed application's documentation to the Helm chart's interface?
Reason for it can vary ... poor Helm chart documentation, poor Helm chart design, Helm chart not in sync with application releases, ... The consequence is that I often need to grep through its templates and logic to figure out how to poke the chart's interface to achieve what I want. I don't think that's reasonable to say that's part of the end-user experience.
None of that seems like a reasonable complaint about Helm itself, unless Helm makes it easy to write poor charts and never document them. When faced with shitty code with shitty docs, maybe the thing to do is to send a PR and make it better. At least a ticket.
This. Almost every chart try to be helpful and hide the upstream configuration of the application. Inevitably, you will sooner or later need to change a config. Now it’s not enough to read the documentation of the application, you also need to map this parameter into whatever values the helm chart translated it to. I wouldn’t even call it an abstraction, since it’s only read in a single location, it’s just a dumb and pointless translation. Total nonsense.
I have several Docker hosts in my home lab as well as a k3s cluster and I'd really like to use k3s as much as possible. But when I want to figure out how to deploy basically any new package they say here are the Docker instructions, but if you want to use Kubernetes we have a Helm chart. So I invariably end up starting with the Docker instructions and writing my own Deployment/StatefulSet, Service, and Ingress yaml files by hand.
nightmares (if anything went wrong i had to blow helm stuff away and start over) ontop of nightmares (kubernetes when i was trying it was tons of namespaces called beta, then you never knew what to update to or when you had to update, or what was incompatible) ontop of the realization that no one should be using kubernetes unless you have over 50 servers running many hundreds of services. Otherwise its just a million times simpler using docker compose
And it STILL uses text-based Go templates instead of a proper language based on structured input and output? This was always my main pain point with Helm and also of many others I talked to. This major upgrade was years in the making and they couldn't add support for a single of many available options like CUE, JSONNET, or KCL? What an utter waste.
Most people in this thread, it seems, just want a simple way to manage Kubernetes manifests, something that keeps track of different settings for different environments and what's in common for each environment in order to generate the final manifests for an environment. If so, Helm is over-engineered for your use-case. Stick with Kustomize or jsonnet.
Helm's contribution (as horrible as text templating on YAML is) is, yes, to be a package manager. Part of a Helm chart includes jobs ("hooks") that can be run at different stages (pre-install, pre-upgrade, etc.) as well as a job to run when someone runs "helm test", and a way to rollback changes ("helm rollback"), which is more powerful than just rolling back a Deployment, because it will rollback changes to CRDs, give you hooks/jobs that can run pre- and post-rollback, etc.
Helm charts are meant to be written by someone with the relevant skills sitting next to the developers, so that it can be handed off to another team to deploy into production. If that's not your organization or process, or if your developers are giving your ops teams Docker images instead of Helm charts, you're probably over-engineering by adopting it.
I really don't like helm. I think we have arrived at abstraction over abstraction over abstraction.
The last project I had to be involved with used kustomize for different environments, flux to deploy, helm to use a helmchart which took in a list of configmaps using "valuesFrom". Not only does kustomize template and merge together yaml but so does the valuesFrom thing, however at "runtime" in the cluster.
There's just not a single chance to get any coherent checking/linting or anything before deployment. I mean how could a language server even understand how all this spaghetti yaml merges together? And note that I was working on this as a developer in a very restricted environment/cluster.
Yaml is too permissive already, people really start programming with it. The thing is, kubernetes resources are already an abstraction. That's kind of the nice thing about it, you can create arbitrary resources and kubernetes is the management platform for them. But I think it becomes hairy already when we create resources that manage other resources.
And also, sure some infrastructure may be "cattle" but at some point in the equation there is state and complexity that has to be managed by someone who understands it. Kubernetes manifests are great for that, I think using a package manager to deploy resources is taking it too far. Inevitably helm charts and the schema of values change and then attention is needed anyway. It makes the bar for entry into the kubernetes ecosystem lower but is that actually a good thing for the people who then fall into it without the experience to solve the problems they inevitably encounter?
Sorry for the rant but given my second paragraph I hope there is some understanding for my frustrations. Having all that said, I am glad they try to improve what has established itself now and still welcome these improvements.
Helm is the number 1 reason I'm looking to leave behind my DevOps/SRE job. Basically every job or project I accept involves working with helm in some capacity and I'm just tired of working with mostly garbage helm charts, especially big meta-charts or having to fork a chart to add a config parameter value override somewhere. Debugging broken chart installs or incomplete upgrades is also nothing but pain. Most helm charts remind me of working with ansible-galaxy roles around ~2015.
Helm shines when you’re consuming vendor charts (nginx-ingress, cert-manager, Prometheus stack). It’s basically a package manager for k8s. Add a repo, pin a version, set values, and upgrade/rollback as one unit. For third-party infra, the chart’s values.yaml provides a fairly clean and often well documented interface
Running my home lab at home, I've grown sick of constant Renovate PRs against the helm charts in use. I recall one "minor" update not long ago recently in CoreDNS was messing with the exposed ports in the service and installs broke for a lot of folks.
If I need to run some software now, I `helm template` the resources and commit those to git. I'm so tired of some random "Extended helm chart to customise labels / annotations in $some resource" change notes. Traefik and Cilium are the only helm charts I use, the rest I `helm template` in to my gitops repo, customize and forget.
At Dayjob in the past, we've debugged various Helm issues caused by the internal sprig library used. We fear updating Argo CD and Helm for what surprises are in store for us and we're starting to adopt the rendered manifests pattern for greater visibility to catch such changes.
So many people complaining about Helm but I'll share my 2 experiences. At my last 2 companies we shipped Helm charts for administrators to easily deploy our stuff.
It worked fine and was simple enough which is what the goal was. But then people came along wanting all sorts of customisations to make the chart configurable to work in their environments. The charts ended up getting pretty unwieldy.
Helm is a product that serves users who like customization to the nth-degree. But everyone else hates it.
Personally, I would prefer it if the 'power users' just got used to forking and maintaining their own charts with all the tweaks they want. The reason they don't do that of course is that it's harder to keep up with updates - maybe that's the problem that needs solving.
As someone who stared out with Helm and has not used any of its alternatives, I had no idea how hated it is. Maybe it's just because of how I use it, but once I got the hang of the template charts I don't feel like I'm running into any hurdles while using it.
56 comments
[ 3.1 ms ] story [ 66.1 ms ] threadAlso, please fix the "default" helm chart template, it's a nightmare of options and values no beginner understands. Make it basic and simple.
Nowadays i would very much prefer to just use terraform for kubernetes deployments, especially if you use terraform anyway!
A one-time adoption from kubectl yaml or helm to terraform is doable - but syncing upstream updates is a chore.
If terraform (or another rich format) was popular as source of truth - then perhaps helm and kubectl yaml could be built from a terraform definition, with benefits like variable documentation, validation etc.
Any tool that encourages templating on top of YAML, in a way that prevents the use of tools like yamllint on them, is a bad tool. Ansible learned this lesson much earlier and changed syntax of playbooks so that their YAML passes lint.
Additionally, K8s core developers don't like it and keep inventing things like Kustomize and similar that have better designs.
but we don't have tons of infra so no idea how it would run for big thousands-of-employees corps.
Helm, and a lot of devops tooling, is fundamentally broken.
The core problem is that it is a templating language and not a fully functional programming language, or at least a DSL.
This leads us to the mess we are in today. Here is a fun experiment: Go open 10 helm charts, and compare the differences between them. You will find they have the same copy-paste bullshit everywhere.
Helm simply does not provide powerful enough tools to develop proper abstractions. This leads to massive sprawl when defining our infrastructure. This leads to the DevOps nightmare we have all found ourselves in.
I have developed complex systems in Pulumi and other CDKs: 99% of the text just GOES AWAY and everything is way more legible.
You are not going to create a robust solution with a weak templating language. You are just going to create more and more sprawl.
Maybe the answer is a CDK that outputs helm charts.
You say you want a functional DSL? Well, jq is a functional DSL!
I liked KRO's model a lot but stringly typed text templating at the scale of thousands of services doesn't work, it's not fun when you need to make a change. I kinda like jsonnet plus the google cli i forget the name of right now, and the abstraction the Grafana folks did too but ultimately i decided to roll my own thing and leaned heavily into type safety for this. It's ideal. With any luck i can open source it. There's a few similar ideas floating around now - Scala Yaga is one.
I've used it in the past (for a quite small deployment I must say), but have been very happy with it. Specifically the diff mode is very powerful to see what changes you'll apply compared to what's currently deployed.
https://github.com/stefanprodan/timoni
There’s packages. You can write functions. You can write tests trivially (the output is basically a giant map that you just write out as yaml)…
I’m applying this to other areas too with great success, for example our snowflake IaC is “just python” that generates SQL. It’s great.
Of course most other programming languages will work just as well, it's just JavaScript being the most natural fit for JSON.
I don't really like this superficial reasoning. You can specify, generate, parse, and validate JSON in many common languages with similar levels of effort.
Saying you should use JavaScript to work with JSON because it has JavaScript in the acronym is about as relevant as comparing Java to JavaScript because both have Java in the name.
But really any kind of reconciler, e.g. flux or argo with helm works very well. Helm is only used as a templating tool, i.e. helm template is the only thing allowed. It works very well and I've ran production systems for years without major issues.
I dont really understand how people have so much trouble with Helm, granted yaml whitespace + go templating is sometimes awful, it is the least bad tool out there that I have tried and once you learn the arcane ways of {{- its mostly a non-issue.
I would recommend writing your own charts for the most part and using external charts when they are simple, or well proven. Most applications you want to run arent that complicated, they are mostly a collection of environment variables, config files, and arguments.
If I could wish for a replacement of helm, it would be helm template with the chart implemented in a typed language, e.g. TypeScript, instead of go template but backwards compatible with go template.
Now it’s not perfect either. It does have some issues with slow querying of the current state during planning, even when it has the tfstate as a cache, which is another source of errors.
terraform with helm/kubernetes/kubectl providers is hit or miss. But I love it for simple things. For hairy things I will want full TypeScript with Pulumi.
E.g. these are the libs I use, generated from CRDs: https://github.com/Extrality/pulumi-crds
> Some common CLI flags are renamed:
> --atomic → --rollback-on-failure > --force → --force-replace
> Update any automation that uses these renamed CLI flags.
I wish software providers like this would realize how fucking obnoxious this is. Why not support both? Seriously, leave the old, create a new one. Why put this burden on your users?
It doesn't sound like a big deal but in practice it's often a massive pain in the ass.
A Helm chart is often a poorly documented abstraction layer which often makes it impossible to relate back the managed application's original documentation to the Helm chart's "interface". The number of times I had to grep through the templates to figure out how to access a specific setting ...
What is the essence of the complaint here? That chart authors do poor jobs? That YAML sucks (it does! it so so does!)? Just that charting provides an abstraction you'd rather not have? (If so, why not just... not use Helm?) Something else?
As said, that I often cannot relate the managed application's documentation to the Helm chart's interface?
Reason for it can vary ... poor Helm chart documentation, poor Helm chart design, Helm chart not in sync with application releases, ... The consequence is that I often need to grep through its templates and logic to figure out how to poke the chart's interface to achieve what I want. I don't think that's reasonable to say that's part of the end-user experience.
PS: I have no gripes with YAML
Helm's contribution (as horrible as text templating on YAML is) is, yes, to be a package manager. Part of a Helm chart includes jobs ("hooks") that can be run at different stages (pre-install, pre-upgrade, etc.) as well as a job to run when someone runs "helm test", and a way to rollback changes ("helm rollback"), which is more powerful than just rolling back a Deployment, because it will rollback changes to CRDs, give you hooks/jobs that can run pre- and post-rollback, etc.
Helm charts are meant to be written by someone with the relevant skills sitting next to the developers, so that it can be handed off to another team to deploy into production. If that's not your organization or process, or if your developers are giving your ops teams Docker images instead of Helm charts, you're probably over-engineering by adopting it.
The last project I had to be involved with used kustomize for different environments, flux to deploy, helm to use a helmchart which took in a list of configmaps using "valuesFrom". Not only does kustomize template and merge together yaml but so does the valuesFrom thing, however at "runtime" in the cluster.
There's just not a single chance to get any coherent checking/linting or anything before deployment. I mean how could a language server even understand how all this spaghetti yaml merges together? And note that I was working on this as a developer in a very restricted environment/cluster.
Yaml is too permissive already, people really start programming with it. The thing is, kubernetes resources are already an abstraction. That's kind of the nice thing about it, you can create arbitrary resources and kubernetes is the management platform for them. But I think it becomes hairy already when we create resources that manage other resources.
And also, sure some infrastructure may be "cattle" but at some point in the equation there is state and complexity that has to be managed by someone who understands it. Kubernetes manifests are great for that, I think using a package manager to deploy resources is taking it too far. Inevitably helm charts and the schema of values change and then attention is needed anyway. It makes the bar for entry into the kubernetes ecosystem lower but is that actually a good thing for the people who then fall into it without the experience to solve the problems they inevitably encounter?
Sorry for the rant but given my second paragraph I hope there is some understanding for my frustrations. Having all that said, I am glad they try to improve what has established itself now and still welcome these improvements.
At Dayjob in the past, we've debugged various Helm issues caused by the internal sprig library used. We fear updating Argo CD and Helm for what surprises are in store for us and we're starting to adopt the rendered manifests pattern for greater visibility to catch such changes.
It worked fine and was simple enough which is what the goal was. But then people came along wanting all sorts of customisations to make the chart configurable to work in their environments. The charts ended up getting pretty unwieldy.
Helm is a product that serves users who like customization to the nth-degree. But everyone else hates it.
Personally, I would prefer it if the 'power users' just got used to forking and maintaining their own charts with all the tweaks they want. The reason they don't do that of course is that it's harder to keep up with updates - maybe that's the problem that needs solving.