Skip to content

PATTERN Cited by 1 source

Kustomize wraps Helm chart

Shape

A single Kustomize kustomization.yaml that composes two responsibilities:

  1. Generates Kubernetes ConfigMaps from source files (the pipeline configs, with hash-suffixed names)
  2. Inflates an upstream Helm chart via helmCharts so the generated ConfigMaps + the inflated chart land in one reconcilable manifest set

Canonical kustomization.yaml shape:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: redpanda-connect

# 1) Generate ConfigMaps from pipeline source files
configMapGenerator:
  - name: connect-streams
    files:
      - config/first-names.yaml
      - config/last-names.yaml
generatorOptions:
  disableNameSuffixHash: false   # hash suffix → rolling restart on change

# 2) Inflate the upstream Helm chart
helmCharts:
  - name: connect
    repo: https://charts.redpanda.com
    version: 3.1.0
    releaseName: redpanda-connect-streams
    namespace: redpanda-connect
    includeCRDs: true
    valuesFile: streams-mode.yaml

Why compose this way

Kustomize and Helm solve different parts of the Kubernetes configuration problem:

  • Helm is good at packaging vendor software — the upstream chart author publishes a parameterised manifest set, you consume it with a values.yaml.
  • Kustomize is good at consumer-side customisation — you take existing manifests (from any source — raw YAML, another Kustomize overlay, or inflated-from-Helm) and apply overlays, generators, and patches.

They compose when your consumer-side customisation needs to both inflate an upstream chart and supply its ConfigMap data with rollout-triggering hash semantics. Neither Helm alone nor Kustomize alone solves the full problem:

  • Helm alone — can't produce hash-suffixed ConfigMap names, so ConfigMap data changes don't trigger rollout without manual intervention.
  • Kustomize alone — can't provide Helm's ecosystem of parameterised vendor charts; you'd have to fork or copy the chart contents.

Preconditions for Argo CD

The helmCharts key in kustomization.yaml is gated behind the --enable-helm Kustomize build flag. For Argo CD to process this, the argocd-cm ConfigMap needs:

kubectl -n argocd patch configmap argocd-cm --type merge -p \
  '{"data":{"kustomize.buildOptions":"--enable-helm --load-restrictor LoadRestrictionsNone"}}'

# Restart repo-server + application-controller
kubectl -n argocd rollout restart deploy/argocd-repo-server
kubectl -n argocd rollout restart deploy/argocd-application-controller 2>/dev/null || \
  kubectl -n argocd rollout restart sts/argocd-application-controller
  • --enable-helm allows the helmCharts directive to execute (off by default because Helm templating is Turing-complete and untrusted charts are a supply-chain concern)
  • --load-restrictor LoadRestrictionsNone allows Kustomize to load files outside the immediate directory (e.g., a parallel config/ directory with pipeline YAMLs)

Without these options, Argo CD silently builds a broken manifest set. Both need to be enabled before the first Application sync.

Seen in

  • sources/2025-12-02-redpanda-operationalize-redpanda-connect-with-gitops — canonical wiki instance. Redpanda's 2025-12-02 tutorial uses this pattern for Redpanda Connect Streams mode — two pipeline YAMLs (config/first-names.yaml, config/last-names.yaml) become a hashed connect-streams-<hash> ConfigMap; the Redpanda Connect Helm chart 3.1.0 is inflated inline with valuesFile: streams-mode.yaml. Editing a pipeline YAML + git push triggers the full chain: Argo CD detects change → runs kustomize build --enable-helm → Kustomize computes new hash + rewrites Helm chart references → emits new manifest set → Argo CD applies → K8s performs rolling restart with graceful shutdown.

Alternatives

  • Argo CD multi-source Helm + values — if you don't need to generate ConfigMaps alongside the chart inflation, the plain multi-source pattern is simpler. Use multi-source for Standalone-mode (config-baked-in-chart-values); use Kustomize-wraps-Helm for Streams-mode (config-in-ConfigMaps-with-hash-rollout).
  • Helm chart fork with embedded ConfigMaps — fork the upstream chart, add ConfigMap templates with content. Loses upstream tracking, wins single-tool simplicity.
  • External controller for ConfigMap-driven rollout — Reloader, Stakater/Reloader, or custom annotation-hash-on-pod-template. Adds a runtime component.

Trade-offs

  • --enable-helm is a platform-wide toggle on Argo CD — enabling it for one Application means all Applications can now inflate Helm charts. Platform-level supply-chain concern.
  • Two-tool toolchain — operators need to understand both Helm and Kustomize semantics; debugging failures requires knowing which tool emitted which error.
  • Kustomize build is deterministic but opaque — the final manifest set is a function of source files + chart version + values + hash inputs; reproducing a historical build requires pinning all of these.
Last updated · 470 distilled / 1,213 read