A Helm post-renderer plugin to process kustomizations embedded inside a chart.
- Helm v3 or v4
- kubectl (latest)
Install from the OCI registry:
helm plugin install oci://ghcr.io/owhelm/helm-kustomize:latest
Download from the OCI registry and use the binary from inside there:
oras pull ghcr.io/owhelm/helm-kustomize:latest- Extract the tarball
- Use
helm-kustomizeas--post-renderer
- The plugin uses the Helm v4 plugin API with subprocess runtime
- It's a post-renderer plugin:
- It expects the Helm chart to contain a special resource, which includes all the relevant files embedded inside of it
- If it finds the special resource inside the chart
- it extracts all the files contained in the special resource into a temporary folder
- it removes the special resource from the chart output
- it outputs the entire remaining contents of the chart into the
all.yamlfile - it updates the
kustomization.yamlto reference theall.yamlunderresourcesif it's not already referenced - it runs
kubectl kustomizeagainst the temporary folder and captures the output - it sends the output back to Helm
The plugin uses a custom Kubernetes resource to embed kustomize files within a Helm chart. This resource is detected during post-rendering and used to apply kustomize transformations.
apiVersion: helm.kustomize.plugin/v1alpha1
kind: KustomizePluginData
metadata:
name: kustomize-files
files:
kustomization.yaml: |
resources:
- all.yaml
patches:
- path: patch.yaml
patch.yaml: |
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
# Additional files can be included as needed
# Supports any file structure required by kustomize- apiVersion: Must be
helm.kustomize.plugin/v1alpha1 - kind: Must be
KustomizePluginData - metadata.name: Identifier for the resource (can be any valid Kubernetes name)
- files: A map where keys are file paths and values are file contents
- File paths can include directories (e.g.,
overlays/production/patch.yaml) - Contents are embedded as strings (potentially using YAML multi-line)
- At minimum, should include a
kustomization.yamlfile
- File paths can include directories (e.g.,
The files map supports nested directory structures by using path separators in the keys:
files:
kustomization.yaml: |
# Main kustomization file
patches/deployment.yaml: |
# Patch file in patches subdirectory
overlays/production/kustomization.yaml: |
# Overlay-specific kustomizationWhen extracted, the plugin will create the appropriate directory structure in the temporary folder.
- The resource must have
apiVersion: helm.kustomize.plugin/v1alpha1andkind: KustomizePluginData - At least one file must be specified in the
filesmap - A
kustomization.yamlfile should be present in the root (though kustomize can work with nested kustomizations) - File contents must be valid YAML or appropriate format for kustomize processing
- This resource is automatically removed from the final chart output after processing
- Multiple
KustomizePluginDataresources in a single chart are not currently supported - The resource is processed before the final render, so kustomize transformations are applied to all chart resources
Some of the use cases below are generic kustomize features, where it excels against Helm.
Add labels, annotations, or other metadata across all resources:
files:
kustomization.yaml: |
resources:
- all.yaml
labels:
- includeSelectors: true
includeTemplates: true
pairs:
team: platform
cost-center: engineering
compliance: pci
commonAnnotations:
managed-by: platform-team
security-scan: enabledWhy use this: Instead of templating these into every resource, kustomize applies them uniformly. Easy to add/remove without touching individual templates.
Override image tags or add digest pinning for security:
files:
kustomization.yaml: |
resources:
- all.yaml
images:
- name: nginx
newTag: 1.21.6
digest: sha256:a5b8b7a...
- name: redis
newName: custom-registry.io/redis
newTag: 7.0-alpineWhy use this: Centralizes image management and enables digest pinning for supply chain security without modifying deployment templates.
Apply sophisticated patches that Helm templating would make unwieldy:
files:
kustomization.yaml: |
resources:
- all.yaml
patches:
- path: add-sidecar.yaml
add-sidecar.yaml: |
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: istio-proxy
image: istio/proxyv2:1.18.0
ports:
- containerPort: 15090
name: http-envoy-promWhy use this: Adding sidecars, init containers, or volume mounts via Helm templating can be complex and error-prone. Kustomize patches are cleaner.
Make surgical changes to specific fields:
files:
kustomization.yaml: |
resources:
- all.yaml
patches:
- target:
kind: Deployment
name: my-app
patch: |-
- op: replace
path: /spec/strategy/type
value: Recreate
- op: add
path: /spec/template/spec/securityContext
value:
runAsNonRoot: true
runAsUser: 1000Why use this: When you need exact control over specific fields, JSON patches are more precise than strategic merges or Helm templating.
Use Helm for:
- Package management and versioning
- Initial resource templating
- Dependency management
Use Kustomize for:
- Final transformations and patches
- Cross-cutting concerns
- Image management
See the examples/ directory for complete working examples:
- simple-app: Basic application with kustomize patches demonstrating replica count and label modifications