Tutorial: Build a Postrenderer Plugin
Build a plugin that adds custom labels to all Kubernetes resources.
Subprocess Runtime
Let's start by building a Postrenderer Plugin with the Subprocess runtime.
Prerequisites
- Install the latest Helm 4 release: v4.3.1
- In your terminal session, alias
helmto the release you downloaded.helm version --shortshould now show the correct Helm version in this terminal session. - Install
mikefarah/yq: https://github.com/mikefarah/yq/#install
1. Create Plugin Directory
You can create this anywhere on your filesystem. For example:
mkdir -p $HOME/code/helm/plugins/label-injector
cd $HOME/code/helm/plugins/label-injector
2. Create plugin manifest
apiVersion: v1
type: postrenderer/v1
name: label-injector
version: 0.1.0
runtime: subprocess
runtimeConfig:
platformCommand:
- command: ${HELM_PLUGIN_DIR}/inject-labels.sh
3. Create Script
#!/usr/bin/env sh
# set -e
cat <&0 | yq '.metadata.labels.postrendered-by = "helm-label-injector-plugin"'
Make it executable:
chmod +x inject-labels.sh
4. Install in Dev Mode and Test
Installing a plugin from your filesystem installs in local dev mode, which does not check the provenance:
% helm plugin install $HOME/code/helm/plugins/label-injector
Installing plugin from local directory (development mode)
Installed plugin: label-injector
As we saw in the CLI Plugin and Getter Plugin tutorials, local dev mode installation creates a symlink from your plugin source directory to the plugins directory. You now have three plugins installed:
% ls -lah $(helm env HELM_PLUGINS)
total 0
drwxr-xr-x@ 5 r6by staff 160B Nov 10 04:04 .
drwxr-xr-x@ 3 r6by staff 96B Jan 21 2025 ..
lrwxr-xr-x 1 r6by staff 41B Nov 10 04:04 demo-getter -> /Users/r6by/code/helm/plugins/demo-getter
lrwxr-xr-x 1 r6by staff 44B Nov 10 03:02 label-injector -> /Users/r6by/code/helm/plugins/label-injector
lrwxr-xr-x 1 r6by staff 41B Nov 10 02:18 system-info -> /Users/r6by/code/helm/plugins/system-info
You can now see your installed Postrenderer plugin details along with the installed CLI and Getter plugins, using helm plugin list:
% helm plugin list
NAME VERSION TYPE APIVERSION PROVENANCE SOURCE
demo-getter 0.1.0 getter/v1 v1 local dev unknown
label-injector 0.1.0 postrenderer/v1 v1 local dev unknown
system-info 0.1.0 cli/v1 v1 local dev unknown
Let's try it out:
% helm create ../mychart
% helm template ../mychart --post-renderer label-injector
You should see labels like this in the output:
metadata:
labels:
postrendered-by: helm-label-injector-plugin
What you built: A Postrenderer plugin using the Subprocess runtime!
Use kustomize as a Post-Renderer
The same pattern wraps an existing tool. This plugin runs kustomize build over the rendered manifests. It requires kustomize on your PATH.
Create a new plugin directory:
mkdir -p $HOME/code/helm/plugins/kustomize-renderer
cd $HOME/code/helm/plugins/kustomize-renderer
apiVersion: v1
type: postrenderer/v1
name: kustomize-renderer
version: 0.1.0
runtime: subprocess
runtimeConfig:
platformCommand:
- command: ${HELM_PLUGIN_DIR}/kustomize.sh
The kustomization reads the rendered manifests from all.yaml. This example sets every Deployment to 3 replicas:
resources:
- all.yaml
patches:
- target:
kind: Deployment
patch: |-
- op: replace
path: /spec/replicas
value: 3
The script writes the manifests from STDIN into a temporary directory next to a copy of the kustomization, then builds it:
#!/usr/bin/env sh
set -e
dir=$(mktemp -d)
trap 'rm -rf "$dir"' EXIT
cp "${HELM_PLUGIN_DIR}/kustomization.yaml" "$dir/"
cat <&0 > "$dir/all.yaml"
kustomize build "$dir"
Make it executable, install the plugin, and try it:
% chmod +x kustomize.sh
% helm plugin install $HOME/code/helm/plugins/kustomize-renderer
% helm template ../mychart --post-renderer kustomize-renderer
The Deployment in the output now has replicas: 3. If kustomize build fails, the script exits non-zero and Helm reports the error.
Let's do this one in Wasm runtime now too…
Wasm Runtime
Prerequisites
- Prerequisites from Subprocess Runtime
- Go 1.25 installed
To-do: add this section