Belajar Helm Chart - Membuat Chart Pertama
Episode 7 of 30

Belajar Helm Chart - Membuat Chart Pertama

Beralih dari pengguna menjadi penulis chart: perintah helm create dan struktur yang dihasilkan, file Chart.yaml sebagai identitas chart, desain values.yaml dengan default yang masuk akal, template dasar Deployment, Service, dan ConfigMap, hingga pengujian chart dengan helm lint.

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

Pendahuluan

Setelah di episode 6 sebelumnya kita membahas konfigurasi chart melalui values — bagaimana memilih nilai yang tepat dan menyusunnya per environment — pada episode kali ini kita membalik perspektif: dari pengguna chart yang tinggal mengisi values, menjadi penulis chart yang mendesain bagaimana chart itu dibuat, diatur, dan diuji.

Mengapa topik ini penting? Di dunia kerja nyata, sebagian besar chart yang kalian pakai bukan dari Bitnami atau public repository — melainkan chart internal yang ditulis tim sendiri untuk aplikasi perusahaan. Chart inilah yang menjadi interface standar antara tim aplikasi dan tim platform: satu cara deploy di semua environment, satu cara konfigurasi, satu cara rollback. Kualitas chart internal menentukan kualitas operasional: chart yang dirancang buruk menghasilkan deployment yang rapuh, values yang membingungkan, dan proses release yang lambat. Sebaliknya, chart yang dirancang baik membuat aplikasi bisa dideploy oleh siapa saja — bahkan yang tidak pernah membaca kode aplikasinya — dengan aman dan konsisten.

Di episode ini kita akan membuat chart pertama secara lengkap: membedah helm create, struktur direktori yang dihasilkan, file Chart.yaml, desain values.yaml yang baik, template dasar untuk Deployment, Service, dan ConfigMap, serta alur pengujian sebelum chart dipakai sungguhan.

Pembahasan Utama

helm create: Chart Baru dalam Satu Perintah

Helm menyediakan scaffold untuk memulai: helm create menghasilkan seluruh struktur chart lengkap dengan template yang berfungsi — bukan sekadar kerangka kosong.

Buat chart baru
helm create frontend

Perintah di atas membuat direktori frontend berisi struktur berikut:

Struktur hasil helm create
frontend/
├── .helmignore
├── Chart.yaml
├── charts/
├── templates/
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests/
│       └── test-connection.yaml
└── values.yaml

Setiap berkas punya peran:

  • Chart.yaml — metadata chart: nama, versi, deskripsi, dependency. Identitas sekaligus KTP chart.
  • values.yaml — nilai default yang menjadi kontrak konfigurasi antara chart dan penggunanya.
  • templates/ — kumpulan template Go yang dirender menjadi manifest Kubernetes; inilah "mesin" chart.
  • templates/_helpers.tpl — helper template yang dipakai ulang banyak resource (label, nama lengkap). Detailnya akan kita bedah di episode 10.
  • templates/NOTES.txt — pesan yang ditampilkan setelah install sukses.
  • charts/ — tempat subchart dependency (dibahas di episode 11).
  • .helmignore — daftar file yang dikecualikan saat chart dikemas (dibahas di episode 16).

Karena hasil helm create adalah chart "demo" yang penuh default, langkah berikutnya hampir selalu adalah menyesuaikannya dengan kebutuhan — termasuk menghapus hpa.yaml dan serviceaccount.yaml jika aplikasi kalian belum butuh, dan mendesain values.yaml ulang. Ingat: scaffold adalah titik awal, bukan produk akhir.

File Chart.yaml: Identitas Chart

Chart.yaml adalah satu-satunya file yang wajib ada di setiap chart. Ia mendeskripsikan siapa chart ini, versi berapa, dan ketergantungannya:

Chart.yaml yang baik
apiVersion: v2
name: frontend
description: A production-grade web frontend deployed with Helm
type: application
version: 0.1.0
appVersion: "1.27.0"
keywords:
  - web
  - frontend
maintainers:
  - name: Arman Dwi Pangestu
    email: arman@company.com
    url: https://github.com/armandwipangestu
dependencies:
  - name: redis
    version: "19.0.0"
    repository: https://charts.bitnami.com/bitnami
    condition: redis.enabled
Gunakan apiVersion: v2 untuk Helm 3

Bidang kuncinya:

  • apiVersion — skema chart. v2 untuk Helm 3 (dan satu-satunya yang didukung Helm 3); v1 hanya untuk chart Helm 2.
  • name — nama chart, harus konsisten dengan nama direktori. Ini identitas yang muncul di helm list.
  • version — versi chart, diikuti semver MAJOR.MINOR.PATCH. Ini adalah versi package, berbeda dari versi aplikasi. Detailnya dibahas di episode 16.
  • appVersion — versi aplikasi yang di-deploy chart ini. Nilainya hanya metadata yang bisa ditembus ke template melalui .Chart.AppVersion.
  • description — satu-dua kalimat; ini yang muncul di helm search.
  • typeapplication (chart yang bisa di-install menjadi aplikasi) atau library (chart khusus berisi helper yang tidak bisa di-install mandiri; dibahas di episode 19).
  • keywords dan maintainers — untuk pencarian di repository dan dokumentasi tanggung jawab.
  • dependencies — daftar chart lain yang dibutuhkan, lengkap dengan constraint versi dan kondisi enable. Dibahas mendalam di episode 11.

Desain values.yaml yang Baik

values.yaml adalah kontrak publik chart kalian — inilah yang dilihat dan diedit pengguna. Desain yang buruk membuat pengguna menebak-nebak; desain yang baik membuat pengguna mengerti tanpa membaca satu baris template pun. Prinsip-prinsipnya:

  1. Default yang masuk akal. Nilai bawaan harus membuat chart bisa di-install dan langsung berfungsi tanpa konfigurasi apa pun. Default yang baik juga aman: resource limit wajar, tidak membuka service ke publik, image dari registry yang benar.
  2. Struktur yang jelas. Kelompokkan nilai secara logis (image:, service:, ingress:, resources:), hindari nilai datar yang berserakan. Struktur bertingkat menandakan hubungan antar nilai.
  3. Komentar sebagai dokumentasi. Setiap parameter diberi komentar yang menjelaskan fungsi, format, dan konsekuensinya — ini sekaligus bahan baku dokumentasi otomatis helm-docs (episode 15).
  4. Required vs optional yang eksplisit. Nilai yang wajib diisi pengguna (misalnya nama domain) dibiarkan kosong dan chart akan menolak instalasi jika kosong — nanti kita lihat caranya dengan fungsi required di episode 9. Nilai opsional diberi default yang aman.
Desain values.yaml yang baik
# -- Jumlah replica Pod aplikasi
replicaCount: 1
 
image:
  # -- Registry dan nama image; wajib disesuaikan dengan registry internal
  repository: nginx
  # -- Tag image: versi rilis atau commit SHA dari CI
  tag: "1.27.0"
  # -- IfNotPresent untuk production, Always untuk development
  pullPolicy: IfNotPresent
 
# -- Sumber daya minimum dan maksimum per Pod
resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi
 
service:
  type: ClusterIP
  port: 80
 
# -- Domain publik; WAJIB diisi di production (dikosongkan = Ingress tidak aktif)
ingress:
  enabled: false
  host: ""
Nilai yang wajib diisi ditandai komentar; yang opsional punya default aman

Tip

Lihat pola ingress.host: "" dengan enabled: false. Ini pola "optional tapi tegas": nilai kosong tidak akan menghasilkan konfigurasi yang setengah jadi. Pendekatan serupa berlaku untuk semua fitur yang menambah attack surface — default false, pengguna yang memutuskan kapan menyalakannya. Chart yang baik membuat pengguna sulit membuat kesalahan, bukan sekadar memberikan kebebasan.

Template Dasar: Deployment, Service, ConfigMap

Inti chart adalah template yang merender manifest. Template menggunakan sintaks Go Template — yang akan kita bedah menyeluruh di episode 8 — tapi untuk sekarang cukup kenali dua hal: .Values.<path> untuk membaca values dan .Release.Name untuk nama release. Berikut chart sederhana namun lengkap:

apiVersion: v2
name: frontend
description: Web frontend deployment chart
type: application
version: 0.1.0
appVersion: "1.27.0"

Perhatikan pola penting yang muncul bahkan di template sekecil ini: nama resource memakai .Release.Name (bukan nama chart) agar satu chart bisa di-install beberapa kali sebagai release berbeda — persis seperti contoh kita di episode sebelumnya: satu chart nginx, release frontend, backend, dst. Label memakai .Chart.Name sebagai identitas aplikasi. Dan semua nilai berasal dari .Values — template tidak berisi "angka ajaib".

Template Service dan ConfigMap mengikuti pola yang sama. Service default:

templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}
  labels:
    app: {{ .Chart.Name }}
spec:
  type: ClusterIP
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
  selector:
    app: {{ .Chart.Name }}

Dan ConfigMap untuk nilai konfigurasi non-rahasia:

templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}
  labels:
    app: {{ .Chart.Name }}
data:
  message.txt: |
    {{ .Values.config.message }}

Ingress bisa ditambahkan dengan guard {{- if .Values.ingress.enabled }} — pola kondisional ini, termasuk cara merapikan whitespace dengan {{- dan -}}, akan kita pelajari di episode 8 dan 10. Untuk episode ini, yang penting adalah paham alurnya: values → template → manifest.

Note

Satu kesalahan klasik penulis chart pemula: menyalin manifest statis langsung ke template tanpa memakai values. Jika seluruh nilai di-hardcode, chart kalian hanyalah kubectl apply yang dibungkus rapi — tidak ada nilainya. Ukuran kualitas sebuah template adalah seberapa banyak "keputusan" yang bisa diubah pengguna lewat values tanpa menyentuh kode.

Menguji Chart Sebelum Dipakai

Chart adalah kode, dan kode harus diuji sebelum dideploy. Helm menyediakan empat tingkat pengujian, dari yang paling murah hingga paling nyata:

Uji statis: helm lint
helm lint frontend

helm lint memeriksa aturan main chart: struktur direktori benar, Chart.yaml valid, template bisa dirender tanpa error. Ini gate pertama di CI/CD. Selanjutnya, periksa hasil render tanpa menyentuh cluster:

Render manifest: helm template
helm template frontend ./frontend

helm template merender seluruh template menjadi manifest lengkap dan mencetaknya ke stdout — alat yang sempurna untuk menguji logika template dengan berbagai kombinasi values:

Render dengan values tertentu
helm template frontend ./frontend --values values-prod.yaml

Tingkat ketiga adalah simulasi penuh:

Simulasi install: --dry-run --debug
helm install frontend ./frontend --namespace web --dry-run --debug

--dry-run me-render dan mengirim manifest ke API server untuk divalidasi (skema dan admission controller), tapi tidak benar-benar membuat resource. --debug menampilkan hasil render mentah bersama informasi tambahan — kombinasi yang paling ampuh untuk menemukan kesalahan konfigurasi sebelum go-live.

Terakhir, tingkat paling nyata — instalasi ke cluster dan verifikasi:

Instalasi sungguhan dan verifikasi
helm install frontend ./frontend --namespace web --create-namespace --wait
kubectl get pods -n web
kubectl get svc -n web

Jika chart kalian mendefinisikan hook test (template templates/tests/test-connection.yaml bawaan helm create), verifikasi bisa diotomatisasi dengan helm test frontend --namespace web — topik yang akan kita dalami di episode 14.

Important

Urutan pengujian ini bukan saran, melainkan disiplin: lint dulu, render dulu, dry-run dulu, baru install. Chart yang gagal helm lint tidak layak masuk repository; chart yang render-nya salah tidak layak menyentuh cluster. Di CI/CD, urutan ini menjadi pipeline bertingkat — dan helm template tanpa flag apa pun adalah check pertama yang paling cepat memberi umpan balik.

Kesalahan Umum Chart Pemula

Sebagai penutup bagian pembahasan, berikut pola-pola kesalahan yang paling sering ditemukan saat review chart internal — kenali sekarang agar tidak mengulanginya:

  • Hardcode nama release dan metadata. Template yang menulis name: frontend alih-alih name: {{ .Release.Name }} membuat chart tidak bisa di-install dua kali dalam satu cluster. Semua identitas yang bisa berbeda per install harus datang dari .Release, .Chart, atau .Values.
  • Lupa trim whitespace. Struktur kontrol tanpa {{- meninggalkan baris kosong di output, menghasilkan YAML yang tidak valid atau manifest yang berantakan. Ini penyebab paling umum helm template menghasilkan output yang "aneh" tapi sulit dijelaskan.
  • Meninggalkan template bawaan yang tidak dipakai. helm create menghasilkan hpa.yaml, serviceaccount.yaml, dan ingress.yaml dengan default aktif. Di cluster tanpa metrics-server, HPA default bisa membuat install gagal; ServiceAccount berlebih bisa ditolak policy RBAC. Hapus template yang tidak dibutuhkan, bukan menonaktifkan nilainya satu per satu.
  • Menaruh secret di values. File values biasanya di-commit ke Git. Password, token, dan kunci yang tertulis di sana menjadi kredensial bocor yang permanen dalam riwayat repo. Pisahkan nilai rahasia sejak hari pertama.
  • Mengubah template tanpa menguji. Setiap perubahan template harus melewati helm lint dan helm template minimal — bahkan sebelum --dry-run. Template yang dites hanya saat install akan membayar ongkos kegagalan di waktu yang paling buruk.

Tip

Jika helm lint mengeluh sesuatu yang tidak kalian mengerti, jalankan helm template frontend ./frontend --debug dan baca output mentahnya. Error render template hampir selalu menyebutkan baris dan kolom yang bermasalah — dan kombinasi --debug + membaca output adalah keterampilan debugging yang akan kalian pakai terus di episode-episode berikutnya.

Penutup

Pada episode 7 ini kita telah membuat chart pertama dari nol: membedah helm create dan struktur yang dihasilkannya (Chart.yaml, values.yaml, templates/, _helpers.tpl, NOTES.txt), mempelajari Chart.yaml sebagai identitas chart dengan apiVersion: v2, version, appVersion, type, hingga dependencies. Kita merancang values.yaml dengan prinsip default yang masuk akal, struktur jelas, dokumentasi lewat komentar, dan pembedaan tegas antara nilai required dan optional. Kita menyusun template dasar Deployment, Service, dan ConfigMap yang memakai .Values dan .Release.Name. Terakhir, kita menerapkan alur pengujian bertingkat: helm linthelm templatehelm install --dry-run --debug → instalasi sungguhan.

Inti yang harus kalian bawa:

  • helm create memberi scaffold berfungsi, bukan produk jadi — desain ulang values.yaml dan hapus template yang tidak dipakai.
  • Chart.yaml memisahkan versi chart (version) dan versi aplikasi (appVersion).
  • values.yaml yang baik membuat pengguna sulit salah; default harus aman dan bisa langsung jalan.
  • Template memakai .Values, bukan angka ajaib — chart tanpa values hanyalah kubectl apply berbalut nama.
  • Uji berjenjang: lint → render → dry-run → install. Jangan lompat ke tahap akhir.

Sekarang kalian bisa membuat chart — tetapi template yang baru saja kalian lihat masih "ajaib": {{ .Values.replicaCount }} bekerja tanpa kita pahami aturannya. Di episode 8 selanjutnya kita membuka kotak ajaib itu: Go Template language dasar — delimiter, pipeline, variabel, struktur kontrol if/with/range, fungsi bawaan seperti default, quote, toYaml, dan cara mengakses objek .Values, .Release, .Chart, hingga .Files. Sampai jumpa di episode 8!