HelmRelease and helm-controller
The HelmRelease CRD turns Helm into a controller-driven, continuously reconciled resource with automated remediation, drift correction, and post-render patching — replacing helm upgrade in CI.
Overview
Why HelmRelease exists
Running Helm from CI means a pipeline holds cluster credentials, runs helm upgrade --install, and then stops caring. A half-failed upgrade sits in a failed state and blocks the next attempt; a hand edit to a Deployment goes unnoticed.
The HelmRelease CRD moves all of that inside the cluster, into a controller that keeps reconciling.
helm-controller performs genuine Helm actions, writes genuine Helm release Secrets, and stays interoperable with the helm CLI. What changes is the trigger (a declarative object, not a pipeline step) and the follow-through (a reconciliation loop with an explicit remediation state machine).
Lineage
The name survived a complete rewrite, so quoting the old API group signals stale experience.
Three capabilities CI cannot give you
- Remediation — install.remediation.retries, upgrade.remediation.retries, rollback or uninstall strategy — A failed release self-heals to a known state, retries a bounded number of times, then stops and alerts instead of thrashing
- Drift detection — driftDetection.mode: enabled — Compares manifests in Helm storage against live objects every interval and corrects them; plain Helm has never had this
- Post-renderers — A kustomize block over the rendered output — Override a field an upstream chart never parameterized, without forking it
Where operational judgment shows
- chart versus chartRef — Implicit HelmChart managed by source-controller, or point at an OCIRepository directly
- chart.spec.version semver range — Whether new chart versions arrive without a Git commit
- valuesFrom with targetPath — How credentials reach an upstream chart without landing in the repo
- dependsOn — Orders releases
- storageNamespace, targetNamespace, releaseName — Where Helm bookkeeping and the workload each live; matters once one namespace hosts several releases of a chart
Defaults to name
- maxHistory — 5
- install crds — Create
- upgrade crds — Skip
- remediation retries — 0
- driftDetection — disabled
> [!TIP] Interviewers use this topic to separate people who ran Helm from people who operated it. Strong answers name these defaults and walk the failure path: failed upgrade, rollback, retry exhaustion, the Remediated condition, and the alert that follows.
Key concepts
- HelmRelease CRD
- helm.toolkit.fluxcd.io/v2, reconciled by helm-controller. Declares the desired state of a Helm release. The controller drives real Helm SDK actions and writes real Helm release Secrets, so helm list and helm get still work against it.
- chart versus chartRef
- Mutually exclusive, exactly one required. spec.chart templates an implicit HelmChart from a HelmRepository, GitRepository, or Bucket sourceRef. spec.chartRef points at an existing OCIRepository, HelmChart, or ExternalArtifact — the current path for OCI-hosted charts.
- valuesFrom with targetPath
- Injects a single ConfigMap or Secret key into a specific dotted path in the values tree, equivalent to a Helm --set. This is how a credential reaches an upstream chart without the rest of the values leaving Git. optional skips a missing source; literal bypasses --set parsing.
- Remediation
- install.remediation.retries and upgrade.remediation.retries define a bounded retry budget, default 0 and -1 for infinite. upgrade.remediation.strategy is rollback (default) or uninstall. remediateLastFailure decides whether the final failure is also remediated or left in place for inspection.
- driftDetection
- mode is enabled, warn, or disabled (default disabled). The controller compares manifests recorded in Helm storage against live objects each interval. enabled corrects, warn only emits events. driftDetection.ignore exempts JSON Pointer paths such as HPA-managed /spec/replicas.
- postRenderers
- A kustomize block applied to the chart output after templating and before apply. Supports strategic-merge patches, JSON 6902 patches, and image overrides. The supported way to change something an upstream chart does not expose, without forking the chart.
- maxHistory
- Number of Helm release revisions retained as Secrets in storageNamespace. Defaults to 5. Too high inflates etcd across many releases; too low removes the revisions rollback depends on.
- storageNamespace and targetNamespace
- storageNamespace is where the Helm release Secrets are written; targetNamespace is where the chart objects are created. Both default to the HelmRelease namespace. releaseName defaults to a namespace-name composition, which is why two HelmReleases of the same chart do not collide.
When to use it
- Deploying any Helm chart under GitOps, where the release definition belongs in Git and the cluster reconciles it continuously
- Consuming third-party charts (ingress-nginx, cert-manager, kube-prometheus-stack) with pinned versions and automated remediation on failed upgrades
- Any release that needs self-healing: automatic rollback on a failed upgrade plus a bounded retry budget rather than a stuck FAILED release
- Charts that need a field the maintainer never parameterised — postRenderers patches the rendered output instead of forking
- Multi-tenant clusters where each release must apply under a tenant ServiceAccount via impersonation
- Ordered rollouts where one release must be healthy before the next starts, expressed with dependsOn rather than pipeline sleeps
Interview questions
- Trace the helm-controller lineage and explain why the API group matters.
- Walk through exactly what happens when a HelmRelease upgrade fails.
- How does HelmRelease drift detection work, and why is it disabled by default?
- How do you supply values to a HelmRelease, including secrets, without committing credentials?
- Compare a HelmRelease to running helm upgrade --install from CI. What do you actually gain?
- An upstream chart does not expose the field you need to change. How do you handle it in Flux?
Sign up free to read the full topic
More DevOps topics
- Golden Paths
- gRPC & Protocol Buffers
- Hardware-in-the-Loop CI
- HashiCorp Vault
- Helm 4 Migration
- Helm vs Kustomize
- High Availability System Design
- How User Requests Travel in Kubernetes
- HTTP 4xx and 5xx in Kubernetes — Which Hop Sent It and How to Fix It
- IaC Governance
- IaC State Management
- Identity, Secrets and Config Errors — Workload Identity, Stale ConfigMaps and Secret Stores
Start free on Cariara · Coding problems · System design studio