Subcharts in Helm don’t inherit values from their parent chart by default, forcing you to explicitly pass them down.
Let’s say you have a parent chart my-app and a subchart redis. You want to configure the redis subchart’s memory limit from my-app’s values.yaml.
my-app/Chart.yaml
apiVersion: v2
name: my-app
description: A Helm chart for my application
version: 0.1.0
appVersion: 1.0.0
dependencies:
- name: redis
version: "16.x.x" # Use a specific version
repository: "https://charts.bitnami.com/bitnami"
my-app/values.yaml
replicaCount: 1
redis:
enabled: true
master:
persistence:
size: 8Gi # This is the value we want to pass to the subchart
If you just helm install my-app . with this setup, the redis subchart will use its own default persistence.size. To make my-app’s redis.master.persistence.size control the subchart, you need to map it in the parent chart’s values.yaml.
my-app/values.yaml (modified)
replicaCount: 1
redis:
enabled: true
master:
persistence:
size: 8Gi # Parent chart's value
# This section maps parent values to subchart values
redis:
master:
persistence:
size: 8Gi # This is the value that will be *used* by the redis subchart
Wait, that looks identical. The trick is how Helm merges values. When you pass values from the parent, they are merged into the subchart’s values. You don’t override the subchart’s values file directly; you provide a new set of values that get merged on top of the subchart’s defaults.
So, the my-app/values.yaml should actually look like this to pass the value down:
my-app/values.yaml (correct)
replicaCount: 1
# This section configures the redis subchart
redis:
master:
persistence:
size: 8Gi
When helm install runs, Helm takes the values from my-app/values.yaml and merges them with the redis subchart’s default values.yaml. The redis section in your parent values.yaml directly corresponds to the structure within the subchart’s values.yaml.
Let’s see this in action. Imagine the redis subchart has a values.yaml like this (simplified):
my-app/charts/redis/values.yaml (simplified subchart defaults)
master:
persistence:
enabled: true
size: 1Gi # Default size
And your parent chart my-app has:
my-app/values.yaml
redis:
master:
persistence:
size: 8Gi # Our desired size
When you run helm install my-app ., Helm does the following:
- Loads
my-app/values.yaml. - Loads the
redissubchart’s defaultvalues.yaml. - Merges
my-app/values.yamlinto theredissubchart’s values. Therediskey in the parent’s values becomes the top-level key for merging into the subchart. - The
redis.master.persistence.sizefrommy-app/values.yaml(which is8Gi) overwrites the defaultsize(1Gi) in the subchart’s merged values.
The final set of values used by the redis subchart will effectively be:
master:
persistence:
enabled: true
size: 8Gi # This value came from the parent chart
This allows you to customize any part of a subchart by mirroring its values.yaml structure within your parent chart’s values.yaml.
The key is that the structure in your parent’s values.yaml that corresponds to a subchart must exactly match the path within that subchart’s values.yaml you intend to override. If the subchart’s values.yaml has redis.master.persistence.size, and you want to set it, your parent’s values.yaml needs a redis.master.persistence.size key.
You can also enable or disable subcharts using this mechanism. If the redis subchart has an enabled flag at its root:
my-app/values.yaml
redis:
enabled: false # This will disable the redis subchart
This works because the redis key in the parent values.yaml is merged into the subchart’s values, and if the subchart’s values.yaml contains an enabled key at the top level, your parent’s value will override it.
The most common pitfall is creating a nested structure in your parent values.yaml that doesn’t align with the subchart’s structure, or forgetting to add the subchart’s name as a top-level key in your parent’s values.yaml when you intend to configure it. For example, if you wanted to configure the redis subchart, and your my-app/values.yaml looked like this:
my-app/values.yaml (incorrect structure for subchart config)
master:
persistence:
size: 8Gi
This would not be merged into the redis subchart because there’s no redis key at the top level of my-app/values.yaml to tell Helm "these values are for the redis subchart." Helm expects the key name in the parent’s values.yaml to match the subchart’s name (or whatever alias you might define in Chart.yaml for the dependency).
You can pass global values that apply to multiple subcharts by nesting them under a common key in your parent’s values.yaml, and then referencing that common key within the specific subchart configurations.
my-app/values.yaml
global:
storageClass: "my-fast-ssd"
replicaCount: 3
redis:
master:
persistence:
size: 8Gi
storageClass: {{ .Values.global.storageClass }} # Reference global value
nginx:
replicaCount: {{ .Values.global.replicaCount }} # Reference global value
Here, global is a special key that Helm processes. Values under global are made available to all subcharts via the .Values.global context. This is distinct from simply passing values directly to a subchart.
The next thing you’ll bump into is managing complex conditional logic for subcharts based on these passed values.