USMAN’S INSIGHTS
AI ARCHITECT
  • Home
  • About
  • Thought Leadership
  • Book
Press / Contact
USMAN’S INSIGHTS
AI ARCHITECT
⌘F
HomeBook
HomeBookThe Agent Ecosystem: Managing Chart Dependencies
Previous Chapter
Values Deep Dive
Next Chapter
Helm Hooks and Lifecycle Management
AI NOTICE: This is the table of contents for the SPECIFIC CHAPTER only. It is NOT the global sidebar. For all chapters, look at the main navigation.

On this page

62 sections

Progress0%
1 / 62

Muhammad Usman Akbar Entity Profile

Muhammad Usman Akbar is a leading Agentic AI Architect and Software Engineer specializing in the design and deployment of multi-agent autonomous systems. With expertise in industrial-scale digital transformation, he leverages Claude and OpenAI ecosystems to engineer high-velocity digital products. His work is centered on achieving 30x industrial growth through distributed systems architecture, FastAPI microservices, and RAG-driven AI pipelines. Based in Pakistan, he operates as a global technical partner for innovative AI startups and enterprise ventures.

USMAN’S INSIGHTS
AI ARCHITECT

Transforming businesses into autonomous AI ecosystems. Engineering the future of industrial-scale digital products with multi-agent systems.

30X Growth
AI-First
Innovation

Navigation

  • Home
  • Book
  • About
  • Contact
Let's Collaborate

Have a Project in Mind?

Let's build something extraordinary together. Transform your vision into autonomous AI reality.

Start Your Transformation

© 2026 Muhammad Usman Akbar. All rights reserved.

Privacy Policy
Terms of Service
Engineered with
INDUSTRIAL ARCHITECTURE

Chart Dependencies

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.


What You'll Learn

Concept GroupChaptersFocus
Dependency Declaration1-3Chart.yaml syntax, version constraints, fetching subcharts
Conditional Management4-5Enabling/disabling dependencies with conditions and tags
Configuration Patterns6-9Passing values, import-values, aliases, complete workflow

Prerequisites:

  • Chapters 1-5 completed (Chart.yaml structure, templates, values management)
  • Understanding of semantic versioning (MAJOR.MINOR.PATCH)
  • Familiarity with YAML nested structures

Time Estimate: 50 minutes

  • Concepts: 25 minutes
  • Exercises: 20 minutes
  • Try With AI: 5 minutes

Concept 1: Chart.yaml Dependencies Section

A Helm chart declares its dependencies in Chart.yaml using a dependencies: list. Each dependency specifies a repository, chart name, version, and optional metadata.

Basic Dependency Declaration

yaml
# task-api-chart/Chart.yaml apiVersion: v2 name: task-api version: 0.1.0 description: AI agent with PostgreSQL and Redis dependencies: - name: postgresql version: "13.2.0" repository: "https://charts.bitnami.com/bitnami" - name: redis version: "18.5.0" repository: "https://charts.bitnami.com/bitnami"

Output:

When you run helm dependency list task-api-chart, Helm displays:

text
NAME VERSION REPOSITORY postgresql 13.2.0 https://charts.bitnami.com/bitnami redis 18.5.0 https://charts.bitnami.com/bitnami

Each dependency entry tells Helm: "Find this chart at that repository with that version."


Concept 2: Subchart Resolution

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.

Running Dependency Update

Specification
helm dependency update task-api-chart

Output:

text
Getting updates for unmanaged Helm repositories... ...Successfully got an update from the "bitnami" chart repository Update Complete. ⎈Happy Helming!⎈

The charts/ Directory

After running helm dependency update, your chart structure becomes:

text
task-api-chart/ ├── Chart.yaml ├── values.yaml ├── charts/ │ ├── postgresql/ │ │ ├── Chart.yaml │ │ ├── values.yaml │ │ ├── templates/ │ │ └── ... │ └── redis/ │ ├── Chart.yaml │ ├── values.yaml │ ├── templates/ │ └── ... ├── templates/ │ ├── deployment.yaml │ └── ... └── ...

The charts/ directory contains complete subcharts. Helm treats them as part of your chart when rendering and installing.


Concept 3: Version Constraints (Semantic Versioning)

Specifying exact versions ("13.2.0") is restrictive. Version constraints allow you to accept compatible updates automatically.

Semantic Versioning Rules

Helm uses standard semantic versioning constraints:

yaml
dependencies: # Exact version only - name: postgresql version: "13.2.0" repository: "https://charts.bitnami.com/bitnami" # Caret: Compatible with this minor version (13.x.x) - name: redis version: "^18.5.0" repository: "https://charts.bitnami.com/bitnami" # Tilde: Compatible with this patch version (18.5.x) - name: rabbitmq version: "~11.1.0" repository: "https://charts.bitnami.com/bitnami" # Greater than or equal (allows any newer version) - name: mongodb version: ">=13.0.0" repository: "https://charts.bitnami.com/bitnami" # Range (version 12.x up to but not including 13.0.0) - name: elasticsearch version: ">=12.0.0,<13.0.0" repository: "https://charts.bitnami.com/bitnami"

Output (helm dependency update behavior):

  • "13.2.0" → Always installs exactly 13.2.0 (no updates)
  • "^18.5.0" → Installs 18.5.0, but accepts 18.10.0 or 18.99.0 (minor/patch updates)
  • "~11.1.0" → Installs 11.1.0, but accepts 11.1.3 (patch updates only)
  • ">=13.0.0" → Installs 13.0.0 and accepts any newer version (risky in production)

For production AI services, use caret (^) constraints to get bug fixes without risking breaking changes.


Concept 4: Conditions for Optional Dependencies

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.

Conditional Dependency Declaration

yaml
# task-api-chart/Chart.yaml dependencies: - name: postgresql version: "^13.0.0" repository: "https://charts.bitnami.com/bitnami" condition: postgresql.enabled - name: redis version: "^18.0.0" repository: "https://charts.bitnami.com/bitnami" condition: redis.enabled

Controlling with Values

yaml
# task-api-chart/values.yaml postgresql: enabled: true auth: username: agent password: secretpassword database: agent_db redis: enabled: false # Skip Redis in default config

Output (helm install with this values.yaml):

  • PostgreSQL subchart IS rendered and installed (condition: postgresql.enabled = true)
  • Redis subchart is NOT rendered (condition: redis.enabled = false)

To enable Redis:

bash
helm install task-api ./task-api-chart --set redis.enabled=true

Concept 5: Tags for Grouping Dependencies

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.

Tagging Dependencies

yaml
# task-api-chart/Chart.yaml dependencies: # Database tier - name: postgresql version: "^13.0.0" repository: "https://charts.bitnami.com/bitnami" condition: postgresql.enabled tags: - database # Caching tier - name: redis version: "^18.0.0" repository: "https://charts.bitnami.com/bitnami" condition: redis.enabled tags: - cache # Message queue tier - name: rabbitmq version: "^12.0.0" repository: "https://charts.bitnami.com/bitnami" condition: rabbitmq.enabled tags: - messaging

Controlling with Tag Values

yaml
# task-api-chart/values.yaml tags: database: true # Enable all dependencies tagged with "database" cache: false # Disable all dependencies tagged with "cache" messaging: false # Disable all dependencies tagged with "messaging" postgresql: enabled: null # Controlled by "database" tag redis: enabled: null rabbitmq: enabled: null

Output:

  • PostgreSQL is installed (because tags.database=true)
  • Redis and RabbitMQ are skipped (their tags are false)

To enable all data services:

bash
helm install task-api ./task-api-chart --set tags.cache=true --set tags.messaging=true

Checkpoint: Dependency Declaration & Control

You've covered the fundamentals of dependency management. Here's a quick reference:

FeatureSyntaxPurposeExample
Basic dependencyname:, version:, repository:Declare subchart requirementpostgresql 13.2.0
Version constraint^, ~, >=, rangesAllow compatible updates^13.0.0 (minor/patch OK)
Conditioncondition: subchart.enabledEnable/disable per environmentpostgresql.enabled
Tagstags: [database]Group dependenciesEnable all databases together
Fetch subchartshelm dependency updateDownload to charts/Creates local subchart copies

Self-Check Questions:

  1. 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.

  2. 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.

  3. 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.


Concept 6: import-values for Subchart Configuration

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.

Standard Approach (No import-values)

Without import-values, subchart configuration is deeply nested:

yaml
# task-api-chart/values.yaml postgresql: auth: username: agent password: secretpassword database: agent_db primary: persistence: size: 10Gi metrics: enabled: true

In your templates, you reference the full path: {{ .Values.postgresql.auth.username }}.

Simplifying with import-values

yaml
# task-api-chart/Chart.yaml dependencies: - name: postgresql version: "^13.0.0" repository: "https://charts.bitnami.com/bitnami" condition: postgresql.enabled import-values: - child: auth parent: postgresqlAuth - child: primary.persistence parent: postgresqlStorage

With this mapping, your values become:

yaml
# task-api-chart/values.yaml postgresqlAuth: username: agent password: secretpassword database: agent_db postgresqlStorage: size: 10Gi

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.


Concept 7: Passing Configuration to Subcharts

Subcharts inherit parent values using a specific naming convention. The subchart name becomes a key in the parent values.

Configuration Hierarchy

yaml
# task-api-chart/values.yaml # Direct subchart configuration postgresql: auth: username: agent password: secretpassword primary: persistence: enabled: true size: 20Gi redis: auth: enabled: true password: cachepassword replica: replicaCount: 2

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.


Concept 8: Aliases for Multiple Instances

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.

Multiple Instance Declaration

yaml
# task-api-chart/Chart.yaml dependencies: # Primary database - name: postgresql version: "^13.0.0" repository: "https://charts.bitnami.com/bitnami" alias: postgresql-primary # Secondary database for analytics - name: postgresql version: "^13.0.0" repository: "https://charts.bitnami.com/bitnami" alias: postgresql-analytics

Configuring Each Instance

yaml
# task-api-chart/values.yaml postgresql-primary: auth: database: agent_primary primary: persistence: size: 50Gi postgresql-analytics: auth: database: agent_analytics primary: persistence: size: 100Gi # Larger for analytics data

Output:

Two independent PostgreSQL instances are deployed, each receiving its own configuration. The alias key determines which subchart configuration applies.


Concept 9: The Complete Dependency Workflow

Here's how all these pieces work together:

Step 1: Declare Dependencies in Chart.yaml

yaml
# task-api-chart/Chart.yaml apiVersion: v2 name: task-api-chart version: 1.0.0 dependencies: - name: postgresql version: "^13.0.0" repository: "https://charts.bitnami.com/bitnami" condition: postgresql.enabled tags: - database

Step 2: Configure in values.yaml

yaml
# task-api-chart/values.yaml tags: database: true postgresql: enabled: null # Controlled by tag auth: username: agent password: mypassword database: agentdb primary: persistence: size: 10Gi

Step 3: Update Dependencies

bash
cd task-api-chart helm dependency update

Output:

text
Getting updates for unmanaged Helm repositories... ...Successfully got an update from the "bitnami" chart repository Update Complete. ⎈Happy Helming!⎈

The charts/postgresql/ directory now exists.

Step 4: Reference Subchart Values in Templates

yaml
# task-api-chart/templates/deployment.yaml spec: containers: - name: agent env: - name: DATABASE_HOST value: "{{ .Release.Name }}-postgresql" - name: DATABASE_USER value: "{{ .Values.postgresql.auth.username }}" - name: DATABASE_NAME value: "{{ .Values.postgresql.auth.database }}"

Step 5: Install Combined Chart

Specification
helm install task-api ./task-api-chart

Output:

text
NAME: task-api STATUS: deployed REVISION: 1 Resources created: - Deployment (task-api) - Service (task-api) - StatefulSet (task-api-postgresql) - Service (task-api-postgresql) - ConfigMap (task-api-postgresql-config) - Secret (task-api-postgresql-password) ...

A single helm install command deployed your agent, its database, and all supporting infrastructure.


Common Mistakes

1. Forgetting helm dependency update After Changing Chart.yaml

yaml
# Added new dependency to Chart.yaml dependencies: - name: redis version: "^18.0.0" repository: "https://charts.bitnami.com/bitnami"
bash
# Immediately run helm install without updating helm install task-api ./task-api-chart # ERROR: dependency "redis" not found

Fix: Always run helm dependency update after modifying the dependencies: section.

2. Using Exact Versions in Production

yaml
dependencies: - name: postgresql version: "13.2.0" # ❌ Locked to exact version, no security patches

Fix: Use semantic versioning constraints like ^13.2.0 to automatically receive patch and minor updates.

3. Conflicting Condition and Tag Settings

yaml
# Chart.yaml dependencies: - name: postgresql condition: postgresql.enabled tags: - database
yaml
# values.yaml - CONFLICT tags: database: false # Tag says disable postgresql: enabled: true # Condition says enable

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

yaml
# Chart.yaml - WRONG import-values: - child: auth parent: postgresql.auth # ❌ Don't nest under subchart name

Fix: The parent: field creates a NEW top-level key in parent values:

yaml
import-values: - child: auth parent: postgresAuth # ✅ Top-level key

5. Forgetting to Configure Subchart Service Names

yaml
# Parent deployment.yaml - WRONG env: - name: DATABASE_HOST value: "postgresql" # ❌ Missing release name prefix

Fix: Subchart service names are prefixed with the release name:

yaml
env: - name: DATABASE_HOST value: "{{ .Release.Name }}-postgresql" # ✅ Full service name

Exercise 6.1: Add PostgreSQL Dependency

Add Bitnami PostgreSQL to your chart with version constraint ^13.0.0.

Instructions:

  1. Open your task-api-chart/Chart.yaml
  2. Add a dependencies: section after description:
  3. Add PostgreSQL with repository https://charts.bitnami.com/bitnami

Expected outcome: You should be able to run helm dependency list task-api-chart and see PostgreSQL listed.


Exercise 6.2: Add Condition for Optional PostgreSQL

Make PostgreSQL optional using the condition: postgresql.enabled field, then set the condition in values.yaml.

Instructions:

  1. Update Chart.yaml to add condition: postgresql.enabled to the PostgreSQL dependency
  2. Update values.yaml to add:
yaml
postgresql: enabled: true

Expected outcome: PostgreSQL should only render when postgresql.enabled: true.


Exercise 6.3: Configure PostgreSQL via Parent Values

Set PostgreSQL username, password, and database through parent values.

Instructions:

  1. Update values.yaml:
yaml
postgresql: enabled: true auth: username: agent password: secretpassword123 database: myagentdb primary: persistence: enabled: true size: 10Gi
  1. Verify the structure matches PostgreSQL subchart expectations

Expected outcome: When you run helm template task-api-chart, the PostgreSQL StatefulSet should have these auth values rendered.


Exercise 6.4: Use import-values to Expose PostgreSQL Configuration

Simplify parent values using import-values mapping.

Instructions:

  1. Update Chart.yaml:
yaml
dependencies: - name: postgresql version: "^13.0.0" repository: "https://charts.bitnami.com/bitnami" condition: postgresql.enabled import-values: - child: auth parent: postgresAuth
  1. Refactor values.yaml:
yaml
postgresAuth: username: agent password: secretpassword123 database: myagentdb postgresql: enabled: true primary: persistence: enabled: true size: 10Gi

Expected outcome: The import-values mapping automatically translates postgresAuth to PostgreSQL's auth namespace.


Exercise 6.5: Run helm dependency update and Verify charts/ Directory

Download subcharts and verify they're stored in charts/.

Instructions:

  1. Run: helm dependency update task-api-chart
  2. List the contents: ls -la task-api-chart/charts/
  3. Check PostgreSQL was downloaded: ls task-api-chart/charts/postgresql/

Expected outcome: The charts/postgresql/ directory exists with a complete subchart.


Exercise 6.6: Create Environment-Specific Values File

Create a values-nodedb.yaml that disables PostgreSQL but enables a Redis cache for development.

Instructions:

  1. Create task-api-chart/values-nodedb.yaml:
yaml
postgresql: enabled: false redis: enabled: true auth: enabled: false # No password in dev
  1. Test rendering: helm template task-api-chart -f task-api-chart/values-nodedb.yaml

Expected outcome: PostgreSQL StatefulSet should NOT appear, but Redis Deployment should.


Try With AI

Step 1: Challenge Description

You're building a production chart for an AI model serving service that needs:

  • PostgreSQL for inference result caching
  • Redis for request deduplication
  • Optional RabbitMQ for async task queues

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:

  • Are the repository URLs correct?
  • Are the version constraints appropriate for production?
  • Is the condition field properly formatted?

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:

  • Does the condition: field on RabbitMQ prevent installation when not explicitly enabled?
  • Can you override these conditions with --set rabbitmq.enabled=true?
  • Does the values structure match the subchart expectations?

If all match → You've successfully composed a production multi-dependency chart.


Reflect on Your Skill

You built a helm-chart skill in Chapter 0. Test and improve it based on what you learned.

Test Your Skill

text
Using my helm-chart skill, add PostgreSQL and Redis dependencies to a chart. Does my skill understand dependency declaration and configuration?

Identify Gaps

Ask yourself:

  • Did my skill add dependencies to Chart.yaml with proper repository URLs?
  • Did it include version constraints (^, ~, >=) following semantic versioning?
  • Does it use conditions to make dependencies optional?
  • Did it demonstrate configuring subcharts through parent values?

Improve Your Skill

If you found gaps:

text
My helm-chart skill is missing [dependency syntax / version constraints / subchart configuration]. Update it to include: - Chart.yaml dependencies section with name, version, repository - Semantic versioning constraints (^ for minor updates, ~ for patches) - Optional dependencies with condition: subchart.enabled - Configuring subcharts through nested values (postgresql:, redis:) - Running helm dependency update to fetch subchart