Which parts of a Helm chart's output never reach a post-renderer's stdin?
answer
- It only sees what templating produced
- One directory is never templated
- Helm writes some objects itself
- Hooks are ordinary rendered files
- crds/ is the exception that bites
basics
~20 sManifests in the chart's crds/ directory are never templated and never enter the stream, so a post-renderer cannot patch them. Helm's own sh.helm.release.v1 record Secret is not rendered either. Everything under templates/, including subchart templates and hook manifests, does go through.
solid answer
~50 sThe post-renderer sees exactly what Helm renders from templates — the chart's own `templates/` and every subchart's — and nothing else. Two things are therefore out of reach. Files in `crds/` are never templated: Helm installs them directly, before the rendered manifests, and they never enter the stream, so a post-renderer cannot fix a CRD in a chart you do not own. Helm's own release record, the `sh.helm.release.v1.<name>.v<rev>` Secret, is written by Helm rather than rendered, so it is likewise untouchable. What **does** go through surprises people in the other direction: hook-annotated manifests are ordinary rendered files and are in the stream, and Helm reads the `helm.sh/hook` annotation after post-rendering — so a transformation that strips or adds that annotation changes whether an object is treated as a hook at all. Files excluded by `.helmignore` never became part of the chart, so they were never candidates.
go deeper
Remember the one-line rule: a post-renderer sees what Helm rendered from templates, and nothing else. If a file was never templated, it cannot be patched this way.
Be able to name the exception and say why: crds/ is installed directly and never goes through the template engine, so it is absent from the stream a post-renderer edits.
Show you have hit the consequences — a defective CRD in someone else's chart has no Helm-side fix, and a blanket annotation pass can silently turn a hook into an ordinary tracked resource.
Use this when judging whether a chart is adoptable at all. A chart whose critical objects live in crds/ gives you no supported patch seam, which is a real argument against depending on it.
The mental model that makes this question easy is that a post-renderer is spliced into exactly one place in Helm's pipeline: it receives the output of **template rendering**. Anything Helm does that is not template rendering is invisible to it. ## What is not in the stream **The `crds/` directory.** Helm treats `crds/` specially and has done since Helm 3. Files there are plain YAML, never run through the template engine, and installed before the rendered manifests so that custom resources in `templates/` have their kinds registered. Because they are never rendered, they never enter the stream the post-renderer receives, and no post-renderer can modify them. This matters more than it sounds. Helm never upgrades and never deletes CRDs installed from `crds/` — that is unchanged in Helm 4 — so a chart you do not own that ships a CRD with a defect leaves you with no Helm-side lever at all: not a value, not a post-renderer. You are down to applying a corrected CRD out of band, or not using that chart's `crds/` path. **Helm's own release record.** Each revision is stored as a Secret named `sh.helm.release.v1.<name>.v<rev>` (or another backend, depending on `HELM_DRIVER`). Helm writes that object itself; it is not rendered from any template, so it is not in the stream. A post-renderer cannot alter, label or annotate it. This is a good example of why the bare word "secret" is dangerous on this topic: a Secret the chart renders from `templates/` is fully editable by a post-renderer, while the release record Secret is not. **Files excluded by `.helmignore`.** These never became part of the chart in the first place, so they were never candidates for rendering, let alone post-rendering. ## What is in the stream, and often surprises people **Subchart templates.** Helm renders the parent chart and all its subcharts together into one stream. That is precisely why post-renderers are useful: the object you cannot configure usually belongs to a subchart you do not own, and it is right there in the stream alongside everything else. **Hook manifests.** A hook is an ordinary file in `templates/` carrying the `helm.sh/hook` annotation. It is rendered like anything else and it is in the stream that the post-renderer receives, because Helm reads the hook annotations after post-rendering to split the stream into hooks and ordinary resources. Two consequences follow. A transformation that blanket-adds annotations to everything can accidentally add or disturb hook metadata; and one that strips the `helm.sh/hook` annotation from a manifest turns that hook into an ordinary resource, which will then be created and, worse, tracked as part of the release rather than run at its event and cleaned up by its `helm.sh/hook-delete-policy`. If your transformation edits annotations, scope it by kind, name or label rather than applying it to every document. ## How to check rather than guess You never have to reason about this from memory. Render the chart with `helm template --post-renderer …` and read what comes back; anything absent from that output was never offered to the post-renderer. That is also the honest way to answer the question in an interview: state the rule — the post-renderer sees rendered templates and only rendered templates — and then name `crds/` as the important exception, because it is the one that quietly defeats a real plan to patch a chart you do not own.
- A third-party chart ships a CRD in crds/ with a field you need changed. What are your options?Not a post-renderer, and not a value — `crds/` is never templated, so neither reaches it. Practically you either apply a corrected CRD out of band and accept that Helm will not manage it, or take a chart variant that ships its CRDs as ordinary templates instead. It is also worth remembering that Helm never upgrades or deletes CRDs installed from `crds/`, so the CRD is a long-lived commitment either way.
- What can go wrong if a post-renderer adds an annotation to every document in the stream?Hook manifests are in that stream, and Helm reads the hook annotations after post-rendering. A blanket annotation pass can disturb `helm.sh/hook`, `helm.sh/hook-weight` or `helm.sh/hook-delete-policy` on those documents, changing whether an object is treated as a hook, when it runs relative to others, or whether it is cleaned up. Scope the transformation by kind, name or label instead.
saying these in an interview costs you the question
- Thinks crds/ manifests are rendered like templates
- Believes a post-renderer can patch a chart's CRDs
- Says hook manifests are excluded from the stream
- Claims subchart templates are rendered separately from the parent
- Thinks the release record Secret can be post-rendered