Mengomposisikan chart besar dari komponen kecil: field dependencies di Chart.yaml, perintah helm dependency, hubungan parent-child dan pewarisan nilai, global values, override subchart, hingga pola lanjutan import-values, condition, tags, dan alias.

Setelah di episode 10 sebelumnya kita membangun named templates dan helper helpers — abstraksi yang membuat satu chart rapi dan konsisten — pada episode kali ini kita naik satu tingkat skala: mengomposisikan chart besar dari chart-chart yang lebih kecil. Topiknya adalah dependencies dan subcharts, mekanisme Helm untuk menyatakan "chart ini membutuhkan chart lain" dan menggabungkannya menjadi satu release.
Mengapa ini penting? Hampir tidak ada aplikasi production yang berdiri sendiri. Sebuah aplikasi web butuh database, mungkin butuh Redis untuk cache, ingress controller untuk traffic, dan redis sentinel untuk failover. Menyalin semua manifest komponen itu ke dalam satu chart raksasa akan menghasilkan chart yang sulit dimaintain dan mustahil di-upgrade parsial. Dependencies memberi kalian mental model yang sama seperti package manager: sama seperti package.json di Node men-deklarasi library yang dibutuhkan aplikasi, dependencies di Chart.yaml men-deklarasi chart pendukung. npm install menarik seluruh dependency dan menguncinya di lockfile; begitu pula helm dependency update. Setelah episode ini, kalian tidak akan lagi menggabungkan chart secara manual — kalian akan mengomposisinya. Dan pola ini juga menjadi jembatan menuju library chart di episode 19, di mana komposisi adalah segalanya.
Dependency dideklarasikan di field dependencies pada Chart.yaml. Setiap entry mendeskripsikan chart yang dibutuhkan, dari mana mengambilnya, dan dalam kondisi apa ia aktif:
apiVersion: v2
name: myapp
description: Aplikasi web dengan database dan cache
type: application
version: 0.1.0
appVersion: "1.16.0"
dependencies:
- name: postgresql
version: "15.5.3"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
- name: redis
version: "19.6.4"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
tags:
- cache
- name: local-helper
version: "0.2.0"
repository: "file://../local-helper"
tags:
- test-utilsMari bedah setiap field yang penting:
name dan version — identitas chart dependency. version di sini bukan sekadar angka: ia adalah version constraint yang bisa memakai rentang seperti ">=1.0.0 <2.0.0", "~1.2", "^1.5.3", atau "1.2.x". Helm memilih versi tertinggi yang cocok dengan constraint saat dependency update.repository — sumber chart. Ini bisa URL HTTP(S) (https://charts.bitnami.com/bitnami), URL OCI (oci://registry-1.docker.io/bitnamicharts), atau path file lokal (file://../local-helper) untuk development.condition — nama path values yang menentukan apakah dependency ikut diaktifkan. Nilai path diperiksa sebagai boolean; jika falsy, dependency di-skip.tags — kumpulan tag yang bisa mengaktifkan/menonaktifkan sekelompok dependency sekaligus dari satu nilai di values.alias — nama alias sehingga chart yang sama bisa di-install dua kali dengan nama berbeda (misalnya dua instance Redis: satu untuk cache, satu untuk queue).Important
Perhatikan perbedaan condition dan tags: condition mengontrol per-dependency, tags mengontrol per-kelompok. Keduanya bisa dikombinasikan — logika yang berlaku adalah OR: sebuah dependency diaktifkan jika kondisi-nya true ATAU semua tag yang melekat padanya true. Kelupaan aturan OR ini adalah salah satu sumber kebingungan paling umum di kalangan pengguna Helm.
Setelah dependencies dideklarasikan, kalian perlu menarik chart-chart tersebut ke direktori charts/. Tiga perintah yang harus kalian hafal:
helm dependency update ./myapp
helm dependency build ./myapp
helm dependency list ./myapphelm dependency update — mengunduh chart dependency sesuai constraint di Chart.yaml, menyimpannya sebagai arsip .tgz di charts/, dan menulis file Chart.lock. Lockfile merekam versi persis yang diunduh, sehingga build berikutnya deterministik.helm dependency build — membaca Chart.lock dan mengunduh versi yang sama persis tanpa mengecek ulang constraint. Ini setara npm ci — dipakai di CI/CD agar build selalu reproducible.helm dependency list — menampilkan tabel status dependency: nama, versi, repository, dan status (ok, missing, wrong version).helm dependency update ./myapp
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 2 charts
Downloading postgresql from repo https://charts.bitnami.com/bitnami
Downloading redis from repo https://charts.bitnami.com/bitnami
Deleting outdated chartsHasil akhirnya adalah struktur seperti ini:
myapp/
├── Chart.lock
├── Chart.yaml
├── charts/
│ ├── postgresql-15.5.3.tgz
│ └── redis-19.6.4.tgz
├── templates/
└── values.yamlKetika chart di-package (episode 16), subchart yang sudah diunduh ikut dibungkus ke dalam arsip. Karena itu, praktik umum di tim adalah me-commit Chart.yaml dan Chart.lock, tapi tidak me-commit charts/*.tgz — pipeline CI yang menjalankan helm dependency build yang menaruhnya. Ini menjaga repository tetap kecil dan mencegah binary hasil build tak sengaja di-commit.
Begitu dependency terunduh ke charts/, ia menjadi subchart dari chart utama (parent). Hubungannya bukan sekadar folder: ia adalah hubungan runtime yang memengaruhi cara nilai diakses dan cara template dirender.
Beberapa fakta penting tentang hubungan parent-child:
condition/tags), dan resource-nya di-install sebagai bagian dari release parent.global values. Ia tidak bisa membaca values.yaml chart sibling.export/import-values yang akan kita bahas).Release.Name parent — jadi jika kalian helm install myapp ./myapp, subchart postgresql akan membuat resource bernama myapp-postgresql. Inilah mengapa dua release dari chart yang sama di cluster yang sama tidak saling bentrok.Analoginya seperti direktori perusahaan: parent adalah departemen, subchart adalah tim di dalamnya. Tim bekerja dengan mandat dan sumber daya yang diberikan departemen, tidak bisa seenaknya memakai sumber daya tim lain, dan seluruh kinerja departemen dinilai sebagai satu kesatuan di depan manajemen (release).
Bagaimana jika kalian ingin sebuah nilai dilihat oleh semua subchart sekaligus? Di sinilah section global di values.yaml berperan. Nilai di bawah global: tersedia untuk parent dan setiap subchart, tidak peduli seberapa dalam letaknya.
global:
imageRegistry: registry.internal.example.com
imagePullSecrets:
- name: regcred
storageClass: fast-ssd
postgresql:
enabled: true
image:
registry: {{ .Values.global.imageRegistry }}
persistence:
storageClass: {{ .Values.global.storageClass }}
redis:
enabled: true
image:
registry: {{ .Values.global.imageRegistry }}Perhatikan bahwa di dalam subchart, nilai global diakses lewat .Values.global.* — subchart postgresql dan redis sama-sama membaca registry dari satu sumber. Ini pola yang sangat berguna untuk hal-hal lintas chart: registry image internal, pull secrets, storage class standar, dan label/nama cluster. Keuntungannya nyata di environment yang memaksa image dimuat dari mirror/registry privat — kalian cukup mengubah satu nilai global alih-alih meng-override registry di setiap subchart satu per satu.
Note
Ada aturan penting dalam pewarisan nilai: nilai global tidak bisa di-override oleh subchart untuk chart lain (subchart tidak bisa "memaksa" nilai ke chart sibling), tapi nilai yang diteruskan parent (non-global) memang di-merge ke dalam values subchart. Jika key yang sama muncul di nilai parent dan default subchart, key parent-lah yang menang — inilah mekanisme override yang akan kita bedah berikutnya.
Override adalah inti dari konfigurasi dependency. Cara kerjanya sederhana dan elegan: di values.yaml parent, buat section dengan nama yang sama dengan nama dependency (atau alias-nya). Nilai di dalam section itu di-merge ke atas default values.yaml subchart.
postgresql:
auth:
username: myapp
database: myapp
existingSecret: myapp-db-secret
primary:
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
memory: 1Gi
persistence:
size: 20Gi
metrics:
enabled: true
redis:
architecture: standalone
master:
resources:
requests:
cpu: 100m
memory: 256MiKunci dari blok ini: kalian hanya menulis nilai yang ingin diubah — selective overrides. Nilai subchart yang tidak kalian sebut tetap memakai default dari values.yaml subchart tersebut. Ini menjaga values.yaml parent tetap ringkas, dan merupakan alasan utama kenapa chart-bitnami menyediakan puluhan nilai tanpa harus diisi semuanya.
Jika kalian tidak ingin repot membaca dokumentasi subchart untuk tahu struktur values-nya, gunakan --set saat install (precedence tertinggi dari episode 6):
helm upgrade --install myapp ./myapp \
--set postgresql.auth.password=$DB_PASSWORD \
--set redis.master.resources.requests.cpu=100mDan untuk melihat nilai yang benar-benar efektif (setelah semua merge) pada release yang sudah ada, helm get values adalah alat debugging paling jujur:
helm get values myapp
helm get values myapp --revision 2Chart production sering butuh lebih dari sekadar override sederhana. Empat pola berikut adalah yang paling sering dipakai:
Secara default, subchart tidak bisa "mengekspor" nilai ke parent. Pola import-values membalik arah ini: subchart bisa mengekspor nilai lewat nilai exports di dalam values.yaml-nya, dan parent mengimpor nilai tersebut.
dependencies:
- name: postgresql
version: "15.5.3"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
import-values:
- child: exports.connection
parent: databaseJika values.yaml subchart berisi:
exports:
connection:
host: "myapp-postgresql"
port: 5432Maka di parent, kalian bisa mengakses {{ .Values.database.host }} — nilai dari subchart yang diimpor ke scope parent. Pola ini sering dipakai untuk mem-connect chart yang saling bergantung: aplikasi utama membaca konfigurasi koneksi database dari subchart-nya.
condition dan tags sudah kita singgung. Kombinasi keduanya menghasilkan kontrol yang sangat halus. Nilai tags didefinisikan di values.yaml parent dan bersifat global terhadap subchart yang memakai tag tersebut:
tags:
cache: false
test-utils: false
redis:
enabled: trueDi contoh di atas, dependency yang menandai dirinya dengan tag cache tidak akan aktif selama tags.cache false — meskipun redis.enabled true. Ini sangat berguna untuk environment development: nyalakan dependency "berat" hanya saat dibutuhkan.
Ingin dua instance subchart yang sama dalam satu release? alias adalah jawabannya:
dependencies:
- name: redis
version: "19.6.4"
repository: "https://charts.bitnami.com/bitnami"
condition: redis-cache.enabled
alias: redis-cache
- name: redis
version: "19.6.4"
repository: "https://charts.bitnami.com/bitnami"
condition: redis-queue.enabled
alias: redis-queueDengan alias, values override-nya menggunakan nama alias, bukan nama asli — redis-cache.master.resources, redis-queue.architecture — dan resource yang dihasilkan pun memakai prefix alias sehingga tidak bentrok. Pola ini sering dipakai untuk cache + queue, atau dua database dengan peran berbeda.
Sejak Helm 3.8, repository juga bisa berupa registry OCI:
dependencies:
- name: redis
version: "19.6.4"
repository: "oci://registry-1.docker.io/bitnamicharts"Kelebihan OCI akan dibahas tuntas di episode 18, tapi untuk konteks dependencies, yang penting diketahui: OCI dependency diunduh dari registry yang sama dengan image container, menggunakan autentikasi yang sama, dan cocok untuk organisasi yang sudah berbasis container registry.
Menutup pembahasan, berikut kebiasaan yang menyelamatkan tim dari masalah dependency:
Chart.lock. Ini adalah sumber kebenaran versi persis; jangan biarkan setiap developer menarik versi berbeda karena constraint yang longgar.helm dependency build di CI/CD, bukan update. build deterministik; update bisa menarik versi baru jika constraint longgar dan lockfile tidak sinkron.">=1.0.0 <2.0.0" membatasi upgrade minor yang aman, sekaligus menghindari major upgrade yang bisa membawa breaking change.values-dev.yaml, values-staging.yaml, values-prod.yaml masing-masing meng-override enabled dan resource sizing dependency sesuai kebutuhan.helm dependency update ./myapp && git add Chart.lock
helm dependency build ./myapp
helm lint ./myapp && helm template myapp ./myapp --debugPada episode 11 ini kalian telah menguasai komposisi chart: mendeklarasikan dependencies di Chart.yaml lengkap dengan version constraints, repository HTTP/OCI/file, serta condition dan tags; menjalankan helm dependency update, build, dan list beserta peran Chart.lock; memahami hubungan parent-child dan aturan pewarisan nilai; berbagi konfigurasi lintas chart lewat section global; meng-override nilai subchart secara selektif; dan menggunakan pola lanjutan import-values, tags, alias, serta OCI registry. Yang terpenting, kalian kini bisa memandang chart sebagai sesuatu yang dikomposisikan, bukan ditulis utuh dari nol — sebuah perubahan cara berpikir yang akan menentukan skala chart yang bisa kalian kelola.
Di episode 12 selanjutnya kita akan membahas hal yang membuat Helm lebih dari sekadar templating: hooks dan manajemen lifecycle — cara menjalankan Job di titik-titik penting siklus hidup release (install, upgrade, rollback, delete), termasuk migrasi database sebelum upgrade dan smoke test setelah install. Pastikan pemahaman kalian tentang hubungan parent-child masih segar, karena hooks bekerja dalam konteks release yang sama yang baru saja kita bangun. Sampai jumpa di episode 12!