Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Organize Charts with Dependencies

Learn to structure Helm charts with dependencies, enabling modular, reusable deployments. This hands-on lesson covers defining requirements, updating dependencies, and managing version constraints for organized Kubernetes applications.

Focus: organize charts with dependencies

Sponsored

You've built a few Helm charts by now — each one a standalone package of Kubernetes manifests. But real-world applications rarely live in isolation. A web app needs a database, a message queue, or a caching layer. Copying those manifests into every chart is a maintenance nightmare. Organizing charts with dependencies solves this: you declare what your chart needs, and Helm fetches, installs, and wires everything together. This lesson shows you how to define, update, and manage dependent charts — turning a tangled mess of YAML into a clean, reusable dependency tree.

The problem this lesson solves

Imagine you maintain a microservice that relies on PostgreSQL, Redis, and a sidecar logging agent. Without dependencies, you either:

  • Copy the same postgresql Deployment, Service, and PVC YAML into every chart that needs a database — violating DRY principles and guaranteeing drift as versions diverge.
  • Expect developers to manually install prerequisites in the correct order, then pass connection strings via brittle scripts.

Both approaches fail at scale. Helm chart dependencies let you declare "this chart requires these subcharts" inside the parent chart. When you run helm install, Helm automatically:

  1. Resolves all dependencies
  2. Downloads them (or references them locally)
  3. Installs them in the correct order
  4. Exposes values for customisation

This keeps your chart focused on its own logic while reusing battle-tested subcharts from registries or local paths.

Core concept / mental model

Think of a Helm chart as an app module in a package manager — similar to package.json in npm or requirements.txt in Python. The file Chart.yaml gains an optional dependencies field, and you can also use a dedicated charts/ directory or a requirements.yaml (deprecated but still seen in older projects).

Definitions: - Parent chart: The chart you're authoring — it consumes dependencies. - Subchart: A child chart installed as part of the parent chart release. Subcharts are regular Helm charts; they have their own templates/, values.yaml, and Chart.yaml. - Dependency resolution: helm dependency update reads your Chart.yaml dependencies, fetches them into charts/, and generates Chart.lock for reproducible builds.

Key mental model: A parent chart's values.yaml can override a subchart's default values by nesting keys under the subchart's name. This is the pattern that makes organizing charts with dependencies so powerful — centralised configuration, modular components.

How it works step by step

1. Declare dependencies in Chart.yaml

Add a dependencies block under apiVersion: v2:

# myapp/Chart.yaml
apiVersion: v2
name: myapp
description: A web app with dependencies
dependencies:
  - name: postgresql
    version: "~12.1.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
  - name: redis
    version: ">=17.0.0"
    repository: "https://charts.bitnami.com/bitnami"
  • name, version, repository are mandatory.
  • condition ties the subchart to a parent value — if postgresql.enabled: false in your values, Helm skips installing that subchart.
  • Use semver ranges: ~12.1.0 means >=12.1.0 <12.2.0; >=17.0.0 means any 17.x or higher.

2. Run helm dependency update

cd myapp
helm dependency update

This: - Downloads the subchart tarballs into charts/ - Generates Chart.lock with exact versions - Removes outdated subcharts

3. Override subchart values

To set the PostgreSQL password and Redis port from the parent chart, add subchart-specific keys:

# myapp/values.yaml
postgresql:
  enabled: true
  auth:
    password: "securepass123"
    database: myapp_db

redis:
  architecture: standalone
  auth:
    enabled: false

Helm merges these with the subchart's default values.yaml — the parent values win.

4. Install the parent chart

helm install myapp-release ./myapp

Helm deploys the parent chart's templates and all subcharts as a single release. You can see them with:

helm status myapp-release
helm get manifest myapp-release | grep -A5 'kind:'

Hands-on walkthrough

Let's build a chart called microblog that depends on Bitnami's PostgreSQL and a local subchart auth-svc.

Step 1: Scaffold the parent chart

helm create microblog
cd microblog

Delete the default templates/ contents — we'll focus on dependencies.

Step 2: Add PostgreSQL dependency

Edit Chart.yaml:

apiVersion: v2
name: microblog
description: A microblogging application
dependencies:
  - name: postgresql
    version: "~12.1.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled

Step 3: Add a local subchart

Create a local chart:

helm create charts/auth-svc
# remove default manifests in auth-svc/templates — we'll keep it minimal

Add it as a dependency (Helm allows file:// URIs for local charts):

# Chart.yaml
  - name: auth-svc
    version: "0.1.0"
    repository: "file://./charts/auth-svc"

Step 4: Update and inspect

helm dependency update

Output:

Getting updates for unmanaged Helm repositories...
…Successfully got an update from the "https://charts.bitnami.com/bitnami" chart repository
Update Complete. Preparing the update…
Downloading postgresql from repo https://charts.bitnami.com/bitnami
Save: charts/postgresql-12.1.0.tgz
Delete: charts/postgresql-12.1.0.tgz (re-downloaded)
Lock file charts/Chart.lock already exists. Overwrite?

Now ls charts/ shows both auth-svc/ directory and the downloaded postgresql-12.1.0.tgz.

Step 5: Override subchart values

Edit values.yaml:

postgresql:
  enabled: true
  auth:
    database: microblog_db
    username: microblog_user
    password: changeme

auth-svc:
  replicaCount: 2

Step 6: Install

helm install my-blog ./microblog

Check that the release includes subchart resources:

kubectl get pods -l app.kubernetes.io/instance=my-blog

You'll see my-blog-postgresql-0 and my-blog-auth-svc-xxx (naming: <release>-<chartname>).

Compare options / when to choose what

Method Use case Pros Cons
Repository dependency (Bitnami, stable) Common infrastructure (DB, cache, message queue) Version pinning, automatic updates Requires network, registry access
Local subchart (file:// path) Own microservices, proprietary components No external registry; direct dev control Must manage versioning yourself
Simple charts/ copy (manual) Quick experiments, no version management No dependency syntax needed No automatic updates; manual sync errors
requirements.yaml (Helm 2 legacy) Older projects not yet migrated Already exists (don't break it) Deprecated; avoid in new charts

Recommendation: For any shared dependency (PostgreSQL, Redis, Prometheus), use a remote repository and pin the minor version. For your own team's services, use local subcharts in a monorepo until you graduate to a private chart repository.

Troubleshooting & edge cases

Error: no repository definition for ... Add the repo first:

helm repo add bitnami https://charts.bitnami.com/bitnami
helm dependency update

Error: version ... not found Check the available versions:

helm search repo bitnami/postgresql --versions

Adjust the version constraint in Chart.yaml.

Subchart values not applied Ensure the parent values.yaml keys match the subchart name exactly — case-sensitive. If the subchart is named postgresql, the key is postgresql:. Use helm get values my-blog to see the merged output.

Duplicate resource names Subcharts automatically prefix resources with the release name and subchart name. If you still get conflicts, avoid hardcoding metadata.name — use Helm's {{ include "<chart>.fullname" . }} template inside subcharts.

Circular dependencies Helm errors if two charts depend on each other. Break the cycle by extracting shared logic into a third chart or using a conditional flag (condition) that one side disables when the other is active.

What you learned & what's next

You now know how to organize charts with dependencies — from declaring dependencies in Chart.yaml to updating them with helm dependency update and overriding subchart values. This modular approach keeps your charts clean, reusable, and aligned with the DRY principle. The mental model of parent/subchart is the foundation of Helm's dependency system.

Key takeaways: - Dependencies live in Chart.yaml under the dependencies key - Run helm dependency update to fetch subcharts into charts/ - Parent values override subchart defaults using the subchart name as a prefix - Use semver constraints to control version ranges - Local subcharts (file://) work well for internal microservices - Avoid circular dependencies and always pin minor versions in production

Next up: Helm Testing with helm test — you'll learn to write hooks and run validation inside your charts, ensuring dependencies are actually healthy after deployment.

Practice recap

Create a new chart myapp that depends on the Bitnami Redis chart (version >=17.0.0) and a local subchart cache-sidecar (in charts/cache-sidecar). Run helm dependency update, override Redis to use standalone mode, and install the chart. Verify that both a Redis pod and your sidecar pod appear under the same release.

Common mistakes

  • Forgetting to run helm repo add for external repositories before helm dependency update — Helm can't fetch from an unknown repo.
  • Overriding subchart values with wrong key names (e.g., PostgreSQL instead of postgresql) — the key must match the subchart name exactly, case-sensitive.
  • Using a semver constraint that's too loose (e.g., * or >=0.0.0) — this can pull breaking changes on update. Always pin to at least minor version (e.g., ~12.1.0).
  • Not regenerating Chart.lock after changing dependency versions — leads to inconsistent installs across environments.

Variations

  1. You can maintain a monorepo with local subcharts and symlink them during development instead of using file:// paths for faster iteration.
  2. For air-gapped environments, pre-download all subchart tarballs into charts/ and remove the repository reference from Chart.yaml — Helm then uses only cached files.
  3. Helm 3 supports OCI-based registries; you can store dependencies in an OCI registry (e.g., oci://registry.example.com/helm-charts) using the same dependency syntax.

Real-world use cases

  • A microservice chart depends on Bitnami's PostgreSQL subchart — when the microservice is deployed, PostgreSQL installs automatically with custom credentials.
  • A CI/CD pipeline updates subchart versions via helm dependency update and builds the full application stack from multiple team-owned charts.
  • A production Helm chart depends on a local logging sidecar subchart from the same repository — updates to the sidecar are pulled in without copying manifests.

Key takeaways

  • Helm chart dependencies declare required subcharts in Chart.yaml, enabling modular and reusable deployments.
  • Run helm dependency update to download subcharts into charts/ and generate a reproducible Chart.lock.
  • Parent chart values override subchart defaults using the subchart name as a nested key — keep them case-sensitive.
  • Use semver constraints (e.g., ~12.1.0) to control version ranges without breaking on minor patches.
  • Local subcharts (file://) are ideal for internal microservices; external ones from repositories suit shared infrastructure.
  • Avoid circular dependencies; always regenerate Chart.lock after modifying dependency versions.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.