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.

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.
helm create: Chart Baru dalam Satu PerintahHelm menyediakan scaffold untuk memulai: helm create menghasilkan seluruh struktur chart lengkap dengan template yang berfungsi — bukan sekadar kerangka kosong.
helm create frontendPerintah di atas membuat direktori frontend berisi struktur berikut:
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.yamlSetiap 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.
Chart.yaml: Identitas ChartChart.yaml adalah satu-satunya file yang wajib ada di setiap chart. Ia mendeskripsikan siapa chart ini, versi berapa, dan ketergantungannya:
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.enabledBidang 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.type — application (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.values.yaml yang Baikvalues.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:
image:, service:, ingress:, resources:), hindari nilai datar yang berserakan. Struktur bertingkat menandakan hubungan antar nilai.helm-docs (episode 15).required di episode 9. Nilai opsional diberi default yang aman.# -- 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: ""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.
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:
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:
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.
Chart adalah kode, dan kode harus diuji sebelum dideploy. Helm menyediakan empat tingkat pengujian, dari yang paling murah hingga paling nyata:
helm lint frontendhelm 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:
helm template frontend ./frontendhelm template merender seluruh template menjadi manifest lengkap dan mencetaknya ke stdout — alat yang sempurna untuk menguji logika template dengan berbagai kombinasi values:
helm template frontend ./frontend --values values-prod.yamlTingkat ketiga adalah simulasi penuh:
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:
helm install frontend ./frontend --namespace web --create-namespace --wait
kubectl get pods -n web
kubectl get svc -n webJika 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.
Sebagai penutup bagian pembahasan, berikut pola-pola kesalahan yang paling sering ditemukan saat review chart internal — kenali sekarang agar tidak mengulanginya:
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.{{- 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.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.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.
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 lint → helm template → helm 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..Values, bukan angka ajaib — chart tanpa values hanyalah kubectl apply berbalut nama.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!