← Back to all stories

Why I Stopped Fighting With Helm and Learned to Love Kustomize

After years of templating trauma, I finally made the switch. Here's what changed my mind.

I was a Helm believer. Charts, values files, the whole ecosystem - I thought it was the way to manage Kubernetes manifests. Then one day, a single misplaced curly brace made me question everything.

πŸ’₯ The Breaking Point

It was a Friday afternoon (because when else do things break?). I was updating our production Helm chart to add a new environment variable. Simple task, right? Just add one line to the values.yaml and update the template.

The problematic template
env:
{{- range $key, $value := .Values.env }}
  - name: {{ $key }}
    value: {{ $value | quote }}
{{- end }}
{{- if .Values.extraEnv }}
{{ toYaml .Values.extraEnv | indent 2 }}  # <- The indent was wrong
{{- end }}

One wrong indent. That's all it took. The deployment went out, pods started crashing, and I spent the next 3 hours debugging YAML templating instead of actual infrastructure problems.

πŸ€” What Was Wrong With Helm

Don't get me wrong - Helm is powerful. But with power comes complexity:

  • Templating syntax is confusing - Go templates inside YAML? My brain hurts.
  • Debugging is painful - helm template --debug only gets you so far
  • Values inheritance is complex - Multiple values files can lead to unexpected overrides
  • The rendered output is hard to review - What actually gets applied?

✨ Discovering Kustomize

Kustomize takes a different approach: instead of templating, it uses overlays and patches. Your base manifests are plain YAML - no templates, no special syntax. Then you layer modifications on top.

kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml

namePrefix: prod-

patches:
  - patch: |-
      - op: replace
        path: /spec/replicas
        value: 3
    target:
      kind: Deployment

The beauty? Every file is valid YAML. You can kubectl apply the base directly. You can see exactly what changes each overlay makes.

πŸ”„ The Migration

Migrating wasn't instant, but it was straightforward:

  1. Run helm template to get the rendered manifests
  2. Split them into logical base files
  3. Create overlays for each environment
  4. Test with kustomize build
πŸ’‘
Pro tip: Start with one service. Don't try to migrate everything at once. Learn the patterns, then scale.

βš–οΈ The Verdict

After 6 months with Kustomize, here's my take:

βœ…

Simpler Mental Model

Base + Patches = Final manifest. That's it.

βœ…

Better Git Diffs

Plain YAML means meaningful code reviews.

βœ…

Native kubectl Support

kubectl apply -k just works.

⚠️

Less Flexible

Complex logic is harder (but maybe that's good?).

Would I go back to Helm? For complex third-party charts, maybe. For my own applications? Kustomize all the way.


What's your experience with Helm vs Kustomize? Share your thoughts!

Share this story