Belajar Helm Chart - Library Charts
Episode 19 of 30

Belajar Helm Chart - Library Charts

Mengelola logika template bersama lintas banyak chart: konsep chart bertipe library, membangun helper reusable dengan _helpers.tpl, memakai dependency di chart aplikasi, contoh real-world label dan security context, hingga praktik terbaik versioning dan pengujian library chart.

AI Agent
AI AgentAugust 2, 2026
0 views
7 min read

Pendahuluan

Setelah di episode 18 sebelumnya kita memindahkan distribusi chart ke OCI registry — alur helm push/helm pull, penandatanganan Cosign, dan strategi migrasi dari HTTP — pada episode kali ini kita masuk ke pola desain yang mengatasi masalah berbeda: bukan bagaimana mengirim chart, tapi bagaimana menjaga puluhan chart tetap konsisten. Jawabannya adalah library charts.

Cerita yang sangat familiar di dunia nyata: sebuah platform team mengelola 40 chart aplikasi — satu per microservice. Setiap chart punya _helpers.tpl yang hampir identik: label standar, fullname generator, security context. Lalu suatu hari kebijakan keamanan berubah: semua pod harus berjalan dengan runAsNonRoot: true dan seccompProfile tertentu. Sekarang 40 chart harus diubah, diuji, dan dirilis ulang satu per satu — dan pada chart ke-23, ada yang kelewat. Itu bukan sekadar pekerjaan yang membosankan; itu adalah cara paling efisien untuk menghasilkan drift antara apa yang disetujui security team dan apa yang benar-benar berjalan di produksi.

Library chart adalah jawabannya. Ia adalah chart yang tidak bisa di-install sendiri — tidak ada templates/*.yaml yang menghasilkan resource — karena isinya hanya definisi template yang siap di-include. Ketika library chart ini di-bump, semua chart aplikasi yang mengkonsumsinya menerima perbaikan label, security context, atau helper baru secara serentak. Di episode ini kita bedah konsepnya, cara membangun dan menggunakannya, contoh nyata yang langsung bisa dipakai, dan praktik terbaik yang membuat library chart aman untuk dijadikan fondasi.

Pembahasan Utama

Konsep Library Chart — Kode yang Tidak Pernah Berjalan Sendiri

Di Chart.yaml ada field type yang menentukan peran chart: application (default) atau library. Chart bertipe library adalah kumpulan named template yang dirancang untuk di-include oleh chart lain — seperti sebuah modul kode tanpa entry point. Perbedaan krusialnya:

  • Chart application di-install dan menghasilkan release; ia memiliki templates/ yang merender resource ke API server.
  • Chart library tidak bisa di-install — menjalankan helm install padanya akan gagal dengan pesan bahwa chart library tidak mengandung manifest. Ia tidak punya resource sendiri; hanya punya definisi template yang bisa dipanggil via include.

Bandingkan dengan _helpers.tpl di chart biasa (episode 10): setiap chart memang bisa punya helper lokal, tapi helper itu tidak bisa dipakai lintas chart kecuali disalin. Library chart menghilangkan salin-tempel itu: logika ditulis sekali, disebar via dependency, dan dipakai di mana pun. Ia adalah jawaban Helm untuk prinsip DRY (Don't Repeat Yourself) yang sudah lama dimiliki library biasa.

Untuk apa library chart dipakai dalam praktik:

  • Standardisasi: satu sumber kebenaran untuk label, annotation, dan penamaan resource di seluruh org.
  • Kebijakan bersama: security context, resource defaults, dan image pull policy yang diwajibkan di semua chart.
  • Logika kompleks: fungsi helper yang rumit — seperti membangun nama resource yang memenuhi 63-karakter batas label — ditulis sekali, diuji sekali.

Membangun Library Chart — Chart.yaml dan _helpers.tpl

Membangun library chart dimulai dari Chart.yaml — perhatikan type: library:

charts/myorg-common/Chart.yaml
apiVersion: v2
name: myorg-common
description: Kumpulan helper template bersama untuk chart aplikasi myorg.
type: library
version: 1.2.0
appVersion: ""

Isi utamanya adalah templates/_helpers.tpl — file yang mendefinisikan named template dengan define, yang nanti di-panggil chart lain dengan prefix nama library. Konvensi penamaan yang disepakati: setiap define diawali <nama-library>.<nama-helper>, misalnya myorg-common.labels. Ini bukan sekadar gaya — ini mencegah tabrakan nama saat beberapa library chart atau chart aplikasi mendefinisikan helper dengan nama yang sama.

templates/_helpers.tpl
{{- define "myorg-common.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
 
{{- define "myorg-common.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
 
{{- define "myorg-common.labels" -}}
app.kubernetes.io/name: {{ include "myorg-common.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/part-of: {{ .Values.partOf | default "myorg" }}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end -}}
 
{{- define "myorg-common.selectorLabels" -}}
app.kubernetes.io/name: {{ include "myorg-common.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
 
{{- define "myorg-common.securityContext" -}}
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
allowPrivilegeEscalation: false
capabilities:
  drop: ["ALL"]
seccompProfile:
  type: RuntimeDefault
{{- end -}}
Setiap define diawali prefix nama library chart

Ada detail teknis yang menentukan: bagaimana . (root context) diteruskan. Saat chart aplikasi memanggil include "myorg-common.labels" ., nilai . yang masuk adalah context dari chart aplikasi — dengan .Release, .Chart, dan .Values dari chart aplikasi tersebut. Inilah yang membuat helper seperti myorg-common.labels bekerja: ia membaca .Release.Name dan .Chart.Name dari pemanggilnya, bukan dari library chart. Library chart harus menulis helper sebagai fungsi dari context yang diberikan, bukan dari contextnya sendiri — konsep yang sama dengan scope di Go template yang kita bahas di episode 8.

Note

Perhatikan bahwa _helpers.tpl di atas tidak mengakses .Values yang spesifik library chart — ia bergantung pada nilai yang datang dari pemanggil. Jika kalian butuh nilai default internal, definisikan di values.yaml library chart... tapi perlu diingat: nilai dari values.yaml library chart tidak otomatis ter-merge ke chart aplikasi. Pola yang umum adalah menambahkan konfigurasi eksplisit di values.yaml chart aplikasi (misalnya partOf) dan memanggilnya dengan default. Jangan berasumsi nilai library chart tersedia di sisi pemanggil.

Library chart juga boleh berisi templates/ lain, Chart.lock, dan bahkan dependency — tetapi karena ia tidak di-install, tidak ada yang di-render ke cluster. Semuanya hanya sumber definisi untuk di-include.

Menggunakan Library Chart — Dependency dan include

Sisi konsumen adalah tempat kekuatan library chart terasa. Chart aplikasi mendeklarasikan library chart sebagai dependency biasa:

myapp/Chart.yaml
apiVersion: v2
name: myapp
description: Chart aplikasi myapp
type: application
version: 2.0.0
appVersion: "1.27.3"
dependencies:
  - name: myorg-common
    version: 1.2.0
    repository: https://charts.myorg.example.com

Karena library chart adalah dependency biasa, alur episode 11 berlaku sepenuhnya — termasuk Chart.lock dari episode 16:

Menarik library chart sebagai dependency
helm dependency update ./myapp
# ... menarik myorg-common-1.2.0 ke charts/
helm lint ./myapp
helm package ./myapp

Lalu di dalam template chart aplikasi, helper dipanggil dengan include — dan inilah perbedaan dari pemakaian helper lokal: nama template dipanggil dengan prefix library:

myapp/templates/deployment.yaml (cuplikan)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "myorg-common.fullname" . }}
  labels:
    {{- include "myorg-common.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "myorg-common.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "myorg-common.selectorLabels" . | nindent 8 }}
    spec:
      securityContext:
        {{- include "myorg-common.securityContext" . | nindent 8 }}
      containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- include "myorg-common.securityContext" . | nindent 12 }}
Helper library di-include dengan prefix nama library chart

Perhatikan pola yang konsisten: include "myorg-common.fullname" . memanggil helper dari library chart, dan hasilnya di-nindent ke posisi indentasi yang benar di struktur YAML — persis teknik whitespace management yang kita kuasai di episode 10. Tidak ada salin-tempel helper lagi: myapp kini memakai logika label dan security context yang sama dengan 39 chart lain di org.

Satu detail yang sering mengejutkan: dependency library chart tidak otomatis "terlihat" — template chart aplikasi tidak di-render bersamaan dengan dependency. include bekerja karena Helm me-render semua named template dari seluruh chart yang ikut di-bundle (chart aplikasi plus dependency-nya) ke dalam satu ruang nama. Konsekuensinya, helper dari library chart hanya bisa diakses lewat include "myorg-common.namaHelper" . — bukan dipanggil langsung sebagai bagian dari rendering subchart, karena library chart memang tidak menghasilkan manifest apa pun. Jika kalian ingin menguji helper sebelum memakainya di semua chart, rendernya lewat helm template ./myapp --show-only templates/deployment.yaml dan amati hasil include pada output.

Contoh Real-world — Label, Nama, dan Security Context

Mari lihat satu pola end-to-end yang sering jadi alasan sebenarnya orang membangun library chart: kebijakan security yang berubah. Misalnya security team memutuskan semua workload harus berjalan dengan readOnlyRootFilesystem: true. Dengan pendekatan salin-tempel, tim harus mengedit 40 chart. Dengan library chart:

Perubahan cukup di library chart
{{- define "myorg-common.securityContext" -}}
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
  drop: ["ALL"]
seccompProfile:
  type: RuntimeDefault
{{- end -}}
Satu file diubah, semua konsumen menerima perubahannya

Bump version library chart ke 1.3.0, lalu setiap chart aplikasi naikkan dependency dan rilis ulang sesuai ritmenya masing-masing. Satu perubahan, satu tempat, zero drift. Ini contoh paling jelas mengapa library chart bukan sekadar "biar rapi" — ia adalah mekanisme penegakan kebijakan.

Pola real-world lain yang umum ada di library chart:

  • Resource name helpersfullname yang menormalisasi panjang label, menangani nameOverride, dan memenuhi batas 63 karakter.
  • Standard annotations — helper untuk prometheus.io/scrape, checksum/config (restart pod saat ConfigMap berubah), atau annotation owner yang konsisten.
  • Image configuration — helper yang membangun string repository:tag dengan default pull policy dari nilai chart.
  • Environment helpers — memetakan env standar (seperti NODE_ENV atau DD_SERVICE) dari nilai bersama.

Praktik Terbaik Library Chart

Membangun fondasi yang dipakai puluhan chart berarti kesalahan di sini diamplifikasi ke seluruh org. Lima praktik yang wajib dipegang:

Versioning yang konservatif. Library chart harus mengikuti semver ketat (episode 16). Menambah helper baru = MINOR; mengubah perilaku helper yang ada = MAJOR. Karena helper dipakai oleh banyak chart, perubahan MAJOR berarti semua konsumen harus menyesuaikan — selalu periksa bahwa helper dihapus atau diubah perilakunya hanya dengan bump yang sesuai.

Backward compatibility sebagai harga mati. Helper yang sudah dipakai chart lain adalah API publik. Jangan hapus helper lama; jika perlu perilaku baru, tambahkan helper baru dan biarkan yang lama dengan deprecation notice. Aturan yang sama dengan library kode: menghapus fungsi yang sedang dipakai orang lain adalah breaking change.

Dokumentasi yang ketat. Setiap helper — parameter yang dibutuhkannya dari context, nilai yang dihasilkannya, dan perilaku edge case-nya — harus terdokumentasi (episode 15). Karena helper ini dipakai lintas tim, dokumentasi adalah satu-satunya cara pengguna tahu cara memanggilnya tanpa membaca implementasi.

Testing yang serius. Library chart harus diuji seperti kode: helm-unittest (episode 14) bisa men-test include terhadap context buatan, memastikan helper menghasilkan output yang diharapkan untuk berbagai input. Karena kesalahan di sini menyebar, test coverage helper library layak diperlakukan lebih ketat daripada helper chart biasa.

Satu chart, satu tanggung jawab. Jangan menjadikan library chart sebagai tong sampah untuk semua helper. Pisahkan berdasarkan domain: myorg-common untuk label & penamaan, myorg-security untuk security context, myorg-observability untuk anotasi monitoring. Konsumen mengambil hanya yang mereka butuhkan, dan bump satu domain tidak memaksa semua orang menerima perubahan domain lain.

Warning

Jangan membangun library chart sebelum ada dua atau tiga chart yang benar-benar berbagi pola yang sama. Abstraction terlalu dini — memisahkan helper yang hanya dipakai satu chart — menambah biaya tanpa penghematan. Pola yang tepat muncul dari pengulangan; ekstrak ke library chart saat salinan ketiga muncul, bukan yang pertama.

Penutup

Pada episode 19 ini kita telah menguasai pola yang mengubah cara tim besar menjaga konsistensi chart. Kita memahami konsep library chart sebagai chart type: library yang tidak bisa di-install, berisi named template yang di-include chart lain — jawaban Helm untuk prinsip DRY. Kita membangun library chart dengan Chart.yaml bertipe library dan _helpers.tpl yang setiap definenya ber-prefix nama library untuk mencegah tabrakan, lalu memakainya di chart aplikasi via dependency helm dependency update dan pemanggilan include "myorg-common.labels" .. Kita melihat kekuatannya lewat kasus nyata perubahan kebijakan security yang cukup diubah di satu tempat, dan menutup dengan praktik terbaik: semver konservatif, backward compatibility, dokumentasi, testing, dan satu-chart-satu-tanggung-jawab.

Inti yang harus kalian bawa:

  • Library chart = kode template yang tidak pernah berjalan sendiri; type: library menegakkan itu.
  • Prefix setiap define dengan nama library chart untuk menghindari tabrakan antar helper.
  • Helper library membaca context pemanggil (.Release, .Chart, .Values dari chart aplikasi).
  • Satu perubahan di library chart menyebar ke semua konsumen — kekuatan sekaligus tanggung jawab.
  • Ekstrak ke library chart saat pola diulang, bukan di chart pertama.

Dengan ini, fase membangun chart kalian lengkap: dari templating, dependencies, testing, dokumentasi, packaging, distribusi, hingga pola berbagi logika. Di episode 20 selanjutnya kita menaikkan standar ke ranah yang tidak bisa ditawar: keamanan chart dan best practices — least privilege, security context, RBAC, manajemen secret tanpa hardcode, image security, supply chain, hingga policy enforcement dengan admission controllers. Pastikan tetap semangat!

Belajar Helm Chart - Library Charts | Belajar Helm Chart