Lesson 14 Dependencies & Subcharts
Theme:

Lab Guide

Build an application chart with PostgreSQL and Redis subcharts, global values, and conditional toggles.

Prerequisites

Task 1: Create a Chart with Dependencies

Step 1 — Scaffold the chart

helm create webapp
cd webapp

Remove the default template files you will not need for this exercise:

rm -rf templates/tests templates/hpa.yaml templates/serviceaccount.yaml

Step 2 — Declare dependencies

Edit Chart.yaml and add the following dependencies block at the bottom:

dependencies:
  - name: postgresql
    version: "~13.2.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
    tags:
      - backend

  - name: redis
    version: "~18.6.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: redis.enabled
    tags:
      - backend

Step 3 — Download dependencies

helm dependency update .

Verify the results:

# Chart.lock should exist
cat Chart.lock

# Archives should be in charts/
ls charts/

You should see postgresql-13.2.x.tgz and redis-18.6.x.tgz in the charts/ directory and a Chart.lock file at the chart root.

Step 4 — Configure subchart values

Replace the contents of values.yaml with:

replicaCount: 1

image:
  repository: nginx
  tag: "1.25"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

# -- Global values shared by all subcharts
global:
  storageClass: "standard"

# -- PostgreSQL subchart overrides
postgresql:
  enabled: true
  auth:
    username: webapp
    database: webapp_db
    password: supersecret
  primary:
    persistence:
      size: 1Gi

# -- Redis subchart overrides
redis:
  enabled: true
  architecture: standalone
  auth:
    enabled: false
  master:
    persistence:
      size: 1Gi

# -- Tags
tags:
  backend: true

Step 5 — Template and inspect

helm template myrelease . | head -100

You should see rendered manifests for your webapp and for the postgresql and redis subcharts.

Step 6 — Install the release

helm install myrelease . --namespace lab14 --create-namespace
kubectl get pods -n lab14
kubectl get svc -n lab14

✓ Check: You should see pods for webapp, postgresql, and redis all starting up. PostgreSQL may take a minute to become Ready.

Task 2: Toggle Dependencies with Conditions and Tags

Step 1 — Disable Redis via condition

helm upgrade myrelease . --namespace lab14 \
  --set redis.enabled=false
kubectl get pods -n lab14

Redis pods should begin terminating. PostgreSQL and webapp remain unaffected.

Step 2 — Disable all backend dependencies via tags

helm upgrade myrelease . --namespace lab14 \
  --set tags.backend=false
kubectl get pods -n lab14

Now both PostgreSQL and Redis are gone. Only the webapp pod remains.

Step 3 — Condition overrides tag

Re-enable PostgreSQL via its condition while the tag is still false:

helm upgrade myrelease . --namespace lab14 \
  --set tags.backend=false \
  --set postgresql.enabled=true
kubectl get pods -n lab14

PostgreSQL should come back because its condition (postgresql.enabled=true) takes precedence over the tag (tags.backend=false). Redis remains disabled because its condition was not explicitly set, so the tag controls it.

Step 4 — Restore full stack

helm upgrade myrelease . --namespace lab14 \
  --set tags.backend=true \
  --set postgresql.enabled=true \
  --set redis.enabled=true

✓ Check: All three workloads (webapp, postgresql, redis) are running again.

Task 3: Global Values and import-values

Step 1 — Verify global value propagation

Render the templates with a custom global value and search for it:

helm template myrelease . \
  --set global.storageClass=gp3 | grep -i storageclass

Both the postgresql and redis PVC templates should reference gp3 as the storage class, demonstrating that the global value flows into all subcharts.

Step 2 — Add import-values

Edit Chart.yaml and add import-values to the postgresql dependency:

dependencies:
  - name: postgresql
    version: "~13.2.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
    tags:
      - backend
    import-values:
      - child: primary.service
        parent: dbService

Step 3 — Use the imported value in a template

Create a ConfigMap that references the imported database service details. Add this to templates/db-config.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "webapp.fullname" . }}-db-config
data:
  DB_HOST: "{{ include "webapp.fullname" . }}-postgresql"
  DB_PORT: {{ .Values.dbService.ports.postgresql | default "5432" | quote }}

Step 4 — Update dependencies and template

helm dependency update .
helm template myrelease . | grep -A5 "db-config"

✓ Check: You should see the ConfigMap with the database port value imported from the postgresql subchart's service definition.

Cleanup

helm uninstall myrelease --namespace lab14
kubectl delete namespace lab14

Summary