PATTERN Cited by 1 source
Kustomize wraps Helm chart¶
Shape¶
A single Kustomize kustomization.yaml that
composes two responsibilities:
- Generates Kubernetes ConfigMaps from source files (the pipeline configs, with hash-suffixed names)
- Inflates an upstream Helm chart via
helmChartsso 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-helmallows thehelmChartsdirective to execute (off by default because Helm templating is Turing-complete and untrusted charts are a supply-chain concern)--load-restrictor LoadRestrictionsNoneallows Kustomize to load files outside the immediate directory (e.g., a parallelconfig/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 hashedconnect-streams-<hash>ConfigMap; the Redpanda Connect Helm chart 3.1.0 is inflated inline withvaluesFile: streams-mode.yaml. Editing a pipeline YAML +git pushtriggers the full chain: Argo CD detects change → runskustomize 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-helmis 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.
Related¶
- systems/kustomize — the wrapping layer
- systems/helm — the wrapped chart
- systems/argocd — the GitOps controller that auto-detects
kustomization.yamland runs the build - concepts/configmap-hash-rollout — the rolling-restart mechanism this pattern unlocks
- concepts/standalone-vs-streams-mode — the deployment-mode decision where this pattern applies (Streams)
- patterns/argocd-multi-source-helm-plus-values — simpler alternative when ConfigMap generation is not needed
- systems/redpanda-connect — canonical consumer