skip to content

Declaring Subcharts

A dependencies entry in Chart.yaml names a subchart, a SemVer range, a repository URL and an alias for pulling one chart twice. Asked because umbrella charts begin here and later stop paying off.

part ofHelmoverview, primer and where to startread it →
on this pageshow

questions

4

What does an entry in a Helm chart's Chart.yaml dependencies list declare?

level: juniorimportance: must knowfreq 76%

answer

  1. One entry, one bundled chart
  2. Three fields do the real work
  3. Which chart, which versions, from where
  4. A range, not a fixed number
  5. Subcharts share the parent's single release

basics

~20 s

Each dependencies entry declares one subchart the chart bundles: name is the chart to fetch, version is a SemVer range the fetched chart must satisfy, and repository says where to fetch it from. Optional fields such as alias refine that.

solid answer

~40 s

In an `apiVersion: v2` chart, `dependencies` is a top-level list in `Chart.yaml`, and each entry declares one subchart the parent bundles. `name` is the chart's published name — it is what Helm looks up in the repository and, by default, the key its values sit under. `version` is a SemVer constraint rather than necessarily an exact number, so `~4.13.2` resolves to the newest chart matching it. `repository` says where to look: an `https://` chart-repository URL, an `oci://` registry path, a `file://` path, a `@name` reference to a locally added repository, or empty when the chart is already vendored. `alias` renames the dependency so the same chart can appear twice. Declaring dependencies is what turns a chart into an umbrella: one `helm install` renders the parent's templates plus every subchart's into a single release.

code

yaml · 13 lines
yaml
apiVersion: v2
name: reranker-platform
description: Recommendation re-ranker and its edge stack
type: application
version: 2.4.7
appVersion: "1.19.3"
dependencies:
  - name: ingress-controller
    version: "~4.13.2"
    repository: https://charts.example.com/public
  - name: session-store
    version: "3.8.1"
    repository: oci://registry.example.com/charts

go deeper

for a junior

Be ready to name the three fields every entry needs — name, version, repository — and to say in one sentence what each one is for. Knowing that a bundled subchart is not a separate release is the point that most often separates answers here.

for a middle

Explain the two-phase mechanic: dependencies are resolved into the parent's charts/ directory by a separate step, and only what is on disk at render time is deployed. Be precise that version constrains the chart version, not appVersion.

for a senior

Show you read the resolved, concrete versions rather than the declared ranges when auditing what a release is running, and that you can spot the failure where dependencies were never resolved so an install silently deployed only the parent.

for a principal

Own the consequence of the declaration: writing a dependency couples two components into one release lifecycle, one rollback and one blast radius. Be able to say when that coupling is worth having and when it should be two releases instead.

## What the list is A Helm chart is a directory holding `Chart.yaml` (metadata), `values.yaml` (defaults), `templates/`, and optionally a `charts/` directory containing other charts. `dependencies` is a top-level list in `Chart.yaml` naming the charts this one bundles. In `apiVersion: v2` charts — the production chart format used by Helm 3 and Helm 4 — that list lives in `Chart.yaml` itself. The older `apiVersion: v1` format kept the same information in a separate `requirements.yaml`; you will still meet it in ancient charts, but you should not author it. ## The fields **`name`** is the name of the chart to pull, spelled exactly as it is published. It is not a free-form label: Helm looks that name up in the repository you point it at, and if the repository has no chart by that name, resolution fails. By default it is also the key under which that subchart's values are addressed from the parent, and the name that appears inside the subchart's own templates as `.Chart.Name`. **`version`** is a SemVer constraint on the *chart* version — not the version of the application the chart deploys, which is a separate `appVersion` field of the subchart's own `Chart.yaml`, and not the Helm CLI version. The constraint may be an exact version (`4.13.2`) or a range (`~4.13.2`, `^4.13.2`, `>=4.13.2 <5.0.0`). Whatever you write, the constraint is only a *request*: what actually ships is the concrete version that resolution picks and records, and that is what a reviewer should read, not the range. **`repository`** tells Helm where to obtain the chart. It is a location, not a nickname for one: a chart-repository base URL over `https://`, an `oci://` registry path, a `file://` path to a chart in the same source tree, `@name` for a repository already added locally, or an empty string when the chart is already sitting in `charts/`. **`alias`** gives the dependency a different name inside this parent, which is what lets you declare the same chart twice. Other optional fields switch a subchart on or off and shape how values flow into it; those are subjects of their own. ## What Helm actually does with the list Two separate things happen at two separate times, and conflating them is the classic beginner error. First, **resolution**: a `helm dependency` step turns each entry into a concrete chart on disk under the parent's `charts/` directory. Nothing about `dependencies` reaches out to a repository while you are installing — if `charts/` is empty and the entries were never resolved, the install simply renders the parent alone and quietly deploys much less than you expected. Second, **rendering**: `helm install` or `helm upgrade` loads the parent chart plus every chart under `charts/` and renders them all together. This is the point that matters most for a beginner: subcharts are **not** separate releases. There is one release, one release name, one revision counter, one release record. Every subchart's templates see the same `.Release.Name`, `.Release.Namespace` and `.Release.Revision` as the parent; each sees its own `.Chart`. `helm uninstall` removes all of it; a rollback rolls all of it back. The manifests produced by parent and subcharts are merged into one set and installed in Helm's fixed order by resource kind, so a subchart's Namespace or ServiceAccount is created before the Deployment that needs it without anyone declaring an ordering. ## The umbrella shape this produces A chart with a handful of dependencies and few or no templates of its own is called an umbrella chart: its job is composition. A platform team might declare a third-party ingress-controller chart from a public repository, an internal cache chart and its own service charts in one `Chart.yaml`, then deploy the whole stack with one command and roll it back with one more. That is genuinely convenient — and it is also the coupling everyone underestimates, because it means those components now share a lifecycle whether or not their owners want to. ## What interviewers listen for That you distinguish the chart version from the app version; that you know the constraint is a range which gets resolved to something concrete; that `repository` is a location; and above all that a subchart is part of *this* release rather than a release of its own.

  • If a dependency entry says version: "~4.13.2", what version is actually running after an install?
    Whatever concrete chart version resolution picked at the time the dependency was last resolved — the newest 4.13.x available then. The range in `Chart.yaml` is a request, not a record. To answer "what is running" you read the resolved version that was pinned when dependencies were built, or inspect the release itself; reading the range alone tells you only what was permitted.
  • Does a subchart get its own release name and its own revision history?
    No. Parent and subcharts render into a single release: one release name, one namespace, one revision counter, one stored record. Every subchart's templates see the same `.Release.Name` and `.Release.Revision`. That is why `helm rollback` on an umbrella reverts every subchart together and `helm uninstall` removes all of them, which is exactly the coupling you are buying.
  • How is a dependency's version different from the subchart's appVersion?
    `version` in the dependency entry constrains the *chart* version — the version of the packaging. `appVersion` is a field in the subchart's own `Chart.yaml` describing the software it deploys, and it is informational: you cannot constrain it from a dependency entry. A chart can ship five chart versions of the same appVersion when only the templates changed.

The dependencies list is a chart's package manifest, the way a package.json or pom.xml names libraries: it says which package, which acceptable versions, and from where — but the result is linked into one deployable, not shipped separately.

saying these in an interview costs you the question

  • Thinking each subchart becomes its own Helm release
  • Treating version as the application version, not the chart version
  • Believing helm install fetches dependencies from the repository
  • Assuming the name field is a free-form label you choose
  • Confusing repository with a locally added repo's nickname only
  • Expecting the declared range to tell you what is deployed

context

open as a page

What forms can the repository field of a Helm chart dependency take?

level: middleimportance: should knowfreq 52%

basics

~20 s

A Helm dependency's repository can be an https chart-repository base URL, an oci:// registry path that Helm appends the chart name to, a file:// path to a chart in the same tree, an @name reference to a locally added repository, or empty when the chart is already vendored under charts/.

open as a page

When does a Helm umbrella chart that declares every service as a subchart stop paying off?

level: seniorimportance: should knowfreq 40%

basics

~20 s

It stops paying off once the services in it stop sharing a lifecycle. One umbrella means one release, one revision and one rollback, so every team's change deploys everything, one failing subchart fails the whole upgrade, and the single stored release record keeps growing.

open as a page

In a Helm chart's dependencies, what does the alias field do?

level: middleimportance: nice to knowfreq 32%

basics

~20 s

alias gives a dependency a different name inside the parent chart, which is what lets the same chart be declared twice in one Chart.yaml. Helm then treats each entry as a separate subchart named by its alias, with its own values key.

open as a page