In what order does Helm apply the resources rendered from a chart's templates/ directory?
answer
- Something fixed decides it, not you
- Not the file name; a document field
- Dependencies before their dependents
- One hard-coded table of Kubernetes kinds
- Namespace first, Ingress and APIService last
basics
~10 sHelm sorts every rendered manifest by Kubernetes kind using a fixed, hard-coded list: Namespace first, then config and RBAC, then Service, then workloads, then Ingress. File names under templates/ do not decide the order.
solid answer
~40 sAfter rendering, Helm splits the output into individual manifests, reads the `kind` of each, and sorts the whole set against a hard-coded install-order table. Roughly: `Namespace`, guardrails such as `ResourceQuota` and `LimitRange`, then `ServiceAccount`, `Secret`, `ConfigMap`, storage, `CustomResourceDefinition`, RBAC, `Service`, then workloads (`DaemonSet`, `Deployment`, `StatefulSet`, `Job`, `CronJob`), and finally `Ingress` and `APIService`. The point is to create the referenced things before the things that reference them. The table is not configurable — a chart author cannot reorder it from `Chart.yaml`, a values file or a flag. File names only break ties *within* one kind, where manifests are ordered by source path; kinds Helm's table does not know are applied last, alphabetically by kind name.
code
bash · 8 lines# Rendered output comes back kind-sorted, whatever the files are called
helm template checkout ./checkout-api | grep '^kind:'
# kind: ServiceAccount
# kind: Secret
# kind: ConfigMap
# kind: Service
# kind: Deployment
# kind: Ingressgo deeper
Be ready to say the one sentence that matters: Helm sorts by Kubernetes kind against a fixed list, and file names do not decide anything. Knowing roughly that Namespace comes first and Ingress near the end is enough.
An interviewer expects the mechanics: the sort key is the manifest's kind, the table is hard-coded, ties inside a kind fall back to the source path, and unknown kinds go last. Explain the dependency logic behind the table's shape.
Show that you know the limits: it is a submission order with no readiness barrier between kinds, and crds/ and hook-annotated manifests sit outside it. Be able to say when a chart has outgrown what the sort can express.
Own the design implication: chart authors get exactly one, non-negotiable ordering, so a system needing real sequencing must express it in the objects themselves or be split into separate releases. Be ready to argue where that line sits for your platform.
### Why Helm needs an order at all A chart's `templates/` directory renders into a pile of independent Kubernetes YAML documents. Kubernetes itself has no notion of a package: if you hand it a Deployment that mounts a ConfigMap that does not exist yet, it will accept the Deployment and the pods will sit unable to start. So the tool submitting the manifests has to pick an order, and Helm's answer is deliberately simple and completely fixed: **sort every manifest in the release by its `kind`, against a hard-coded table.** ### The install order After the templates are rendered, Helm splits the output into individual manifests, reads the `kind` field out of each document's head, and sorts the list by that kind's index in the install-order table. Reading it top to bottom, the table runs approximately: `PriorityClass`, `Namespace`, then cluster guardrails (`NetworkPolicy`, `ResourceQuota`, `LimitRange`, `PodDisruptionBudget`), then identity and configuration (`ServiceAccount`, `Secret`, `ConfigMap`), then storage (`StorageClass`, `PersistentVolume`, `PersistentVolumeClaim`), then `CustomResourceDefinition`, then RBAC (`ClusterRole`, `ClusterRoleBinding`, `Role`, `RoleBinding`), then `Service`, then the workload kinds (`DaemonSet`, `Pod`, `ReplicationController`, `ReplicaSet`, `Deployment`, `HorizontalPodAutoscaler`, `StatefulSet`, `Job`, `CronJob`), and finally `Ingress` and `APIService`. The rationale is dependency-shaped rather than alphabetical: the namespace exists before anything is placed in it; the ServiceAccount and the ConfigMap exist before the pod template that names them; the PersistentVolumeClaim exists before the StatefulSet that binds it; the Service exists before the pods that will back it, so endpoints populate as soon as pods pass readiness; the Ingress comes last because it points at a Service that must already be there. ### What does not influence the order **File names do not.** Naming a template `00-namespace.yaml` or `zz-deployment.yaml` changes nothing across kinds — the sort key is the kind, not the path. The convention of numeric file prefixes is borrowed from tools that really do apply in lexical order, and carrying it into a chart produces a directory that lies about what happens. **Directory layout does not.** Sub-directories under `templates/` are purely organisational; their manifests join the same flat sorted list. **Declaration order does not.** The order of entries under `dependencies:` in `Chart.yaml` governs value merging and rendering, not the order objects reach the API server. ### The two tie-breaks worth knowing Within a single kind, manifests are ordered by their source path, compared as strings. Two ConfigMaps in `templates/a-config.yaml` and `templates/b-config.yaml` therefore apply in that order — deterministic, but only ever a tie-break inside one kind, never a way to hop a ConfigMap past a Deployment (it is already ahead of it) or a Job in front of one (it is not). A kind that is absent from the table — typically a custom resource introduced by some CustomResourceDefinition — sorts **after** every known kind, with unknown kinds ordered alphabetically by kind name among themselves. That is usually what you want: your custom resource lands after the workloads and the CRD that defines it. ### What sits outside the sort entirely Two things are not part of it. Files in the chart's top-level `crds/` directory are not templated and are installed before the sorted manifests — and they are never upgraded and never deleted afterwards. And any manifest carrying the `helm.sh/hook` annotation is pulled out of the main list altogether and executed at its own event, which is the escape hatch Helm offers for ordering the kind sort cannot express. ### Order is submission, not readiness The most important qualifier: this is the order in which Helm *sends* objects, one after another, with no readiness barrier between kinds. Helm does not wait for the ConfigMap to be observed or the Service to have endpoints before it sends the Deployment. Any waiting that happens is a gate at the end of the whole release, not a per-kind checkpoint. ### Seeing it for yourself `helm template` prints the manifests in exactly this sorted order, and the manifest stored in the release record — what `helm get manifest` gives back — is that same sorted concatenation. If you have ever wondered why `helm get manifest` seems to have shuffled your files, that is why: you are looking at install order, not directory order.
- Two ConfigMaps in a chart sit in different template files. What decides which one Helm applies first?Their source path, compared as a string. Within one kind Helm falls back to ordering manifests by the file they came from, so `templates/a-config.yaml` precedes `templates/b-config.yaml`. It is a deterministic tie-break inside a kind only — it never moves a manifest across the kind boundary.
- Where in the order does Helm apply a custom resource whose kind is not in its table?Last. Any kind Helm does not recognise sorts after every known kind, and unknown kinds are ordered alphabetically by kind name among themselves. In practice that means your custom resources land after the Deployments and after the CustomResourceDefinition rendered from `templates/`.
- Can a chart author change Helm's install order?Not the table itself — it is compiled into Helm and there is no flag, values key or `Chart.yaml` field that reorders it. The only supported way to express ordering the sort cannot is the `helm.sh/hook` annotation family, which lifts a manifest out of the sorted set and runs it at a chosen point in the release.
It is like a builder who always pours the foundation, then runs the pipes, then frames the walls — regardless of the order the drawings were handed over.
saying these in an interview costs you the question
- Says Helm applies templates in alphabetical file-name order
- Thinks numeric file prefixes like 01- control apply order
- Believes Helm waits for each object to be ready before the next
- Claims the install order is configurable in Chart.yaml
- Confuses the kind sort with hook annotations on a manifest
- Thinks nesting a template in a sub-directory changes its position