In Chapters 1-5, you built sophisticated Helm charts from scratch: advanced templating, named helpers, and multi-environment values management. But professional AI deployments rarely start with nothing. Your AI agent needs PostgreSQL for state storage, Redis for caching, and perhaps RabbitMQ for message queues.
Instead of writing database charts yourself, you'll use community charts maintained by Bitnami and others. Helm dependency management is how you compose these public charts into your custom chart—a single helm install deploys your agent, its database, and all supporting services together.
This chapter teaches how to declare, configure, and manage chart dependencies—transforming your custom chart into an orchestration layer that composes production infrastructure.
Prerequisites:
Time Estimate: 50 minutes
A Helm chart declares its dependencies in Chart.yaml using a dependencies: list. Each dependency specifies a repository, chart name, version, and optional metadata.
Output:
When you run helm dependency list task-api-chart, Helm displays:
Each dependency entry tells Helm: "Find this chart at that repository with that version."
Declaring a dependency is not enough—Helm must fetch the actual chart files. The helm dependency update command downloads subcharts and stores them in a charts/ directory.
Output:
After running helm dependency update, your chart structure becomes:
The charts/ directory contains complete subcharts. Helm treats them as part of your chart when rendering and installing.
Specifying exact versions ("13.2.0") is restrictive. Version constraints allow you to accept compatible updates automatically.
Helm uses standard semantic versioning constraints:
Output (helm dependency update behavior):
For production AI services, use caret (^) constraints to get bug fixes without risking breaking changes.
Not every deployment needs every dependency. A developer environment might skip PostgreSQL (using SQLite instead), while production requires it. The condition: field gates whether a subchart is installed.
Output (helm install with this values.yaml):
To enable Redis:
When you have many optional dependencies, managing them individually is tedious. The tags: field groups dependencies, so you can enable/disable groups with a single condition.
Output:
To enable all data services:
You've covered the fundamentals of dependency management. Here's a quick reference:
Self-Check Questions:
Version Constraints: If you declare version: "^18.5.0" for Redis, will Helm accept version 19.0.0?
AnswerNo. Caret (^) allows minor and patch updates within the same major version (18.x.x), but not major version changes.
Conditions vs Tags: When would you use condition: instead of tags:?
AnswerUse condition: for individual dependency control. Use tags: when grouping related dependencies (like all caching services) for bulk enable/disable.
Missing helm dependency update: What happens if you add a dependency to Chart.yaml but skip helm dependency update?
AnswerHelm install will fail with a "dependency not found" error because the subchart files don't exist in charts/ yet.
Subcharts have their own values.yaml files with configurations. You configure them through your parent values, but exposing subchart settings directly clutters your values file. The import-values: field re-exports selected subchart values to your parent namespace.
Without import-values, subchart configuration is deeply nested:
In your templates, you reference the full path: {{ .Values.postgresql.auth.username }}.
With this mapping, your values become:
In templates: {{ .Values.postgresqlAuth.username }} (cleaner namespace).
Output:
When Helm renders, the import-values mapping translates postgresqlAuth back to the subchart's auth namespace, so PostgreSQL receives the correct configuration.
Subcharts inherit parent values using a specific naming convention. The subchart name becomes a key in the parent values.
Output (how subcharts receive values):
When Helm renders the postgresql subchart, it has access to .Values.postgresql.* configuration. The subchart's templates reference its own .Values.auth.username, but the parent passes it via .Values.postgresql.auth.username.
Helm automatically translates the hierarchy: parent's postgresql: key becomes subchart's root values.
Sometimes you need the same chart multiple times with different configurations (two PostgreSQL instances for different databases, or two Redis caches for different use cases). The alias: field enables this.
Output:
Two independent PostgreSQL instances are deployed, each receiving its own configuration. The alias key determines which subchart configuration applies.
Here's how all these pieces work together:
Output:
The charts/postgresql/ directory now exists.
Output:
A single helm install command deployed your agent, its database, and all supporting infrastructure.
1. Forgetting helm dependency update After Changing Chart.yaml
Fix: Always run helm dependency update after modifying the dependencies: section.
2. Using Exact Versions in Production
Fix: Use semantic versioning constraints like ^13.2.0 to automatically receive patch and minor updates.
3. Conflicting Condition and Tag Settings
What happens: The condition: field takes precedence over tags:, so PostgreSQL WILL be installed (enabled=true wins).
Fix: When using both conditions and tags, set individual enabled: to null and control via tags only.
4. Incorrect import-values Mapping
Fix: The parent: field creates a NEW top-level key in parent values:
5. Forgetting to Configure Subchart Service Names
Fix: Subchart service names are prefixed with the release name:
Add Bitnami PostgreSQL to your chart with version constraint ^13.0.0.
Instructions:
Expected outcome: You should be able to run helm dependency list task-api-chart and see PostgreSQL listed.
Make PostgreSQL optional using the condition: postgresql.enabled field, then set the condition in values.yaml.
Instructions:
Expected outcome: PostgreSQL should only render when postgresql.enabled: true.
Set PostgreSQL username, password, and database through parent values.
Instructions:
Expected outcome: When you run helm template task-api-chart, the PostgreSQL StatefulSet should have these auth values rendered.
Simplify parent values using import-values mapping.
Instructions:
Expected outcome: The import-values mapping automatically translates postgresAuth to PostgreSQL's auth namespace.
Download subcharts and verify they're stored in charts/.
Instructions:
Expected outcome: The charts/postgresql/ directory exists with a complete subchart.
Create a values-nodedb.yaml that disables PostgreSQL but enables a Redis cache for development.
Instructions:
Expected outcome: PostgreSQL StatefulSet should NOT appear, but Redis Deployment should.
Step 1: Challenge Description
You're building a production chart for an AI model serving service that needs:
Set up a chart with these three dependencies, but make RabbitMQ optional (disabled by default).
Step 2: Initial Setup
Ask AI to generate the Chart.yaml with proper dependency declarations using the patterns you learned:
"I'm building a Helm chart for an AI model server. Create Chart.yaml with three dependencies: PostgreSQL (^13.0.0), Redis (^18.0.0), and RabbitMQ (^12.0.0) from Bitnami. Make RabbitMQ optional with condition: rabbitmq.enabled. Use semantic versioning constraints to allow patch updates."
Step 3: Configuration Review
Review the generated Chart.yaml and ask:
If the output is missing the condition: field for RabbitMQ or uses exact versions, request corrections.
Step 4: Values Configuration
Ask AI to generate matching values.yaml:
"Generate values.yaml for this chart with: postgresql.enabled=true, redis.enabled=true, rabbitmq.enabled=false. Include basic auth configuration for PostgreSQL (username: agent, database: agentdb)."
Step 5: Verification
Compare your AI-generated files against the requirements:
If all match → You've successfully composed a production multi-dependency chart.
You built a helm-chart skill in Chapter 0. Test and improve it based on what you learned.
Ask yourself:
If you found gaps: