Flux CD Flux CD

Deploy Helm Charts with HelmRelease

Install and upgrade Helm charts from Helm repositories and OCI registries, with automatic rollback.

12 min Intermediate

Flux deploys Helm charts through its own helm-controller. You declare a source that holds the chart and a HelmRelease that says which chart, which version, and which values. The controller then runs the Helm install and upgrade for you, on a schedule, with the whole release lifecycle handled declaratively. This guide uses the public podinfo chart as an example.

Declare the chart source

A HelmRepository tells source-controller where charts live. apps/podinfo/helmrepository.yaml:

apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: podinfo
  namespace: podinfo
spec:
  interval: 1h
  url: https://stefanprodan.github.io/podinfo

By itself this only lists what charts are available. Nothing is installed yet. The source can live in the application’s namespace or in flux-system, and either is fine.

Declare the release

apps/podinfo/helmrelease.yaml:

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: podinfo
  namespace: podinfo
spec:
  interval: 10m
  chart:
    spec:
      chart: podinfo
      version: "6.x"
      sourceRef:
        kind: HelmRepository
        name: podinfo
      interval: 1h
  install:
    remediation:
      retries: 3
  upgrade:
    remediation:
      retries: 3
  values:
    replicaCount: 2
    ui:
      color: "#34577c"

The parts that matter:

  • chart.spec names the chart, a version or semver range (6.x follows new minor and patch releases), and the source it comes from.
  • interval is how often Flux checks the release for changes and drift.
  • values is the equivalent of a values.yaml, written inline. For larger configuration, load values from ConfigMaps or Secrets with valuesFrom.
  • remediation controls what happens when an install or upgrade fails. After the allowed retries, an upgrade failure triggers a rollback to the last good release by default.

Add a plain namespace.yaml for podinfo in the same folder, then register the folder with a Flux Kustomization exactly like in the first-application guide:

flux create kustomization podinfo \
  --source=GitRepository/flux-system \
  --path=./apps/podinfo --prune=true --interval=10m \
  --export > clusters/dev/podinfo.yaml

Commit and push. Once the podinfo Kustomization is reconciled, check the release:

flux get helmreleases -A
kubectl get all -n podinfo

You’ll see the release, the chart version that was installed, and the Pods Helm created. The Helm release itself is still visible to the normal Helm CLI too (helm list -n podinfo), but treat Git as the place you change it.

Per-environment values

Layer environment-specific configuration on top of shared defaults by keeping a base release and patching it per environment with Kustomize, or by using valuesFrom:

spec:
  valuesFrom:
    - kind: ConfigMap
      name: podinfo-values
      valuesKey: values.yaml

Values from valuesFrom are merged first, and inline values override them. When a referenced ConfigMap or Secret changes, the helm-controller picks the change up and upgrades the release, which is different from a plain ConfigMap that a Deployment reads. For config that is baked into the chart’s own ConfigMap, add a checksum annotation to the chart’s Pod template so Pods restart when the config changes:

  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}

Charts from an OCI registry

Helm charts increasingly live in OCI registries. Use a HelmRepository of type oci:

apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: podinfo-oci
  namespace: podinfo
spec:
  type: oci
  interval: 1h
  url: oci://ghcr.io/stefanprodan/charts

The HelmRelease stays the same except for its sourceRef, which points at podinfo-oci. For private registries, add secretRef with registry credentials. You can also reference a chart through an OCIRepository source, which lets several releases share one chart version and reconcile on changes to the artifact’s digest.

Drift detection and upgrades

Out of the box, the helm-controller re-applies a release when its spec or chart changes. To also detect and correct manual edits to the resources a release created, enable drift detection:

spec:
  driftDetection:
    mode: enabled

Without it, a manual kubectl edit of a chart-managed Deployment can persist until the next upgrade. Pair it with interval so Flux regularly compares reality against the release.

Roll back and troubleshoot

flux get helmreleases -A
kubectl describe helmrelease podinfo -n podinfo
flux reconcile helmrelease podinfo -n podinfo

describe shows the Helm action that failed and its error. If an upgrade fails, the controller rolls back automatically based on your remediation settings, and the HelmRelease reports the failure so you can fix Git. The durable fix is always a commit, for example reverting a chart version bump, followed by a reconcile.

Popular Guides