Helm Postrender with Kustomize for Safeguards Compliance
Context and Problem Statement
AKS Automatic Deployment Safeguards require every container to have readiness/liveness probes, resource requests/limits, and seccomp profiles. Most upstream Helm charts (ECK operator, cert-manager, elastic-bootstrap) do not expose all of these fields as configurable values. We need a repeatable pattern to inject missing fields without forking upstream charts or maintaining custom chart versions.
Decision Drivers
- Must work with any upstream Helm chart without forking
- Must be composable: each chart gets its own patch set
- Must integrate with Terraform's
helm_releaseresource viapostrenderblock - Must be auditable: patches are declarative YAML files in version control
- Must not require chart-specific knowledge beyond the target resource kind/name
Considered Options
- Helm postrender with kustomize patches
- Fork upstream Helm charts
- Replace all Helm charts with raw Kubernetes manifests
- Contribute patches upstream to each chart
Decision Outcome
Chosen option: "Helm postrender with kustomize patches", because it provides a single, repeatable pattern for making any Helm chart AKS safeguards-compliant without forking or maintaining custom chart versions.
Consequences
- Good, because a single pattern works for all charts. New chart additions follow the same recipe
- Good, because patches are declarative kustomize YAML, easy to review and audit
- Good, because upstream chart upgrades require only verifying the patch target still exists (kind + name)
- Good, because integrates natively with Terraform
helm_releasevia thepostrenderblock - Bad, because each chart needs a postrender shell script + kustomization.yaml + patch files (boilerplate)
- Bad, because kustomize strategic merge patches must target the correct resource kind and name from the chart output. If a chart renames a resource, the patch silently becomes a no-op
- Bad, because debugging postrender failures requires inspecting intermediate YAML (pipe
helm templatethrough the script manually)
Validation
- Each postrender script is executable (
chmod +x) helm template <chart> | ./<path>/postrender.shproduces YAML with injected probeskubectl get pods -A -o json | jq '.items[].spec.containers[].readinessProbe': no null values in safeguarded namespaces
Pros and Cons of the Options
Helm Postrender with Kustomize
Helm's --post-renderer flag pipes rendered manifests through an external command. We use a shell script that runs kubectl kustomize to apply strategic merge patches.
Pattern per chart: - <chart-dir>/postrender.sh: shell script (stdin → kustomize → stdout) - <chart-dir>/kustomize/kustomization.yaml: patch references - <chart-dir>/kustomize/<resource>-patch.yaml: strategic merge patches
Examples in this repo: - software/foundation/charts/elastic/postrender.sh (ECK operator probes) - software/foundation/charts/cert-manager/postrender.sh (cert-manager probes) - software/stack/kustomize/postrender.sh (OSDU service patches) - software/stack/modules/elastic/postrender.sh (Elasticsearch patches) - software/stack/modules/minio/postrender.sh (MinIO patches)
- Good, because works with any Helm chart without modification
- Good, because patches are version-controlled and declarative
- Good, because composable: multiple patches per chart, one pattern for all charts
- Neutral, because requires
kubectlavailable at apply time (bundled with AKS toolchain) - Bad, because boilerplate per chart (script + kustomization + patches)
- Bad, because patch target (kind/name) must match chart output exactly
Fork Upstream Charts
Maintain internal copies of each Helm chart with probes/resources injected directly in templates.
- Good, because no postrender complexity. Standard Helm workflow
- Bad, because fork maintenance burden multiplied per chart
- Bad, because upstream security patches require manual merge into each fork
- Bad, because divergence from upstream makes community support harder
Raw Kubernetes Manifests for Everything
Replace all Helm charts with hand-authored Kubernetes YAML, giving full control over every field.
- Good, because complete control. No patches needed
- Good, because no dependency on Helm or kustomize
- Bad, because loses Helm's templating, release management, and rollback
- Bad, because dramatically increases YAML volume and maintenance burden
- Bad, because makes upgrading components much harder (no
helm upgrade)
Contribute Patches Upstream
Submit PRs to each upstream chart to expose probe/resource/seccomp configuration as Helm values.
- Good, because benefits the entire community
- Good, because eliminates need for postrender once merged
- Bad, because upstream maintainer timelines are outside our control
- Bad, because some charts have design philosophies that resist these changes
- Bad, because does not solve the immediate deployment need
More Information
- Helm Post Rendering
- Kustomize Strategic Merge Patches
- Implementation:
software/foundation/charts/elastic/postrender.sh,software/foundation/charts/elastic/kustomize/ - Related: ADR-0002 (why safeguards exist)