Mengubah nilai (values) menjadi kontrak yang terjamin: membedah struktur values.schema.json, properti validasi (type, required, enum, pattern, oneOf/anyOf), validasi otomatis saat helm install/upgrade, conditional schema, hingga benefit nyata bagi pengguna dan IDE autocompletion.

Setelah di episode 12 sebelumnya kita membahas hooks — mekanisme Helm untuk menjalankan tindakan di titik-titik kritis siklus hidup release — pada episode kali ini kita membahas sesuatu yang mungkin tidak terlihat glamor tapi justru menjadi pembeda antara chart amatir dan chart production-grade: schema validation dengan JSON Schema.
Pikirkan momen ketika kalian mengonsumsi chart publik. Kalian membuka values.yaml, mengubah beberapa key, lalu menjalankan helm install. Beberapa detik kemudian Helm merender template, mengirim manifest ke API server Kubernetes, dan — jika salah menulis tipe data atau lupa field wajib — kalian baru tahu setelah mendapat error cryptic dari Kubernetes atau malah aplikasi yang jalan dalam keadaan salah. Itulah masalah yang diselesaikan JSON Schema: validasi dilakukan sebelum template dirender, dengan pesan error yang jelas dan bisa dibaca manusia.
Kenapa ini penting di dunia nyata? Sebuah chart dipakai oleh banyak tim, kadang tim yang sama sekali tidak tahu isi values.yaml. Mereka akan menyalin contoh dari README, mengubah-ubah, dan berharap terbaik. Tanpa schema, setiap kesalahan kecil — replicas: "3" padahal harus angka, storageClass yang diketik salah, ingress.enabled yang bukan boolean — menjadi bom waktu yang meledak jauh setelah install. Dengan schema, kesalahan itu ditolak di gerbang depan dengan pesan seperti "replicas: Invalid type. Expected: integer, given: string". Bukan hanya melindungi pengguna chart, schema juga melindungi kalian sebagai pembuat chart dari ratusan support ticket yang seharusnya tidak pernah ada.
values.schema.json dan Cara KerjanyaJSON Schema adalah standar terbuka untuk mendeskripsikan dan memvalidasi struktur data JSON. Karena values.yaml pada dasarnya direpresentasikan sebagai JSON (YAML adalah superset JSON), Helm memanfaatkan standar ini untuk memvalidasi nilai yang diberikan user sebelum chart di-render.
Ketika chart kalian berisi file values.schema.json di root direktori chart (sejajar dengan values.yaml), Helm secara otomatis memvalidasi setiap nilai yang akan digunakan — baik default di values.yaml maupun override yang diberikan lewat --set, --values, atau -f — menggunakan schema tersebut. Validasi terjadi pada setiap helm install, helm upgrade, dan juga helm template jika kombinasinya memungkinkan. Jika nilai tidak sesuai schema, operasi berhenti segera dengan pesan error, sebelum satu pun manifest dikirim ke cluster.
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1
},
"image": {
"type": "object",
"properties": {
"repository": { "type": "string" },
"tag": { "type": "string" }
}
}
},
"required": ["replicaCount", "image"]
}Perhatikan bahwa schema menyebut $schema yang menunjuk ke versi draft tertentu. Helm mendukung JSON Schema draft-07 dan draft-2020-12 (sejak Helm 3.14), dan menyesuaikan validasi dengan versi yang dideklarasikan. Ini penting karena ada perbedaan sintaks — misalnya format penulisan kondisi antar draft — dan kalian harus konsisten dengan versi yang kalian pilih.
Validasi sendiri dilakukan oleh library Go internal Helm, bukan dengan memanggil tool eksternal. Konsekuensinya, semua fungsi yang didukung library tersebut yang tersedia — dan fitur-fitur paling esensial JSON Schema (yang akan kita bahas di bagian properti) semuanya didukung penuh.
Inti dari schema adalah mendeskripsikan bentuk data yang boleh diterima setiap key. Helm akan menolak nilai yang melanggar deskripsi tersebut. Berikut properti-properti yang paling sering dipakai:
| Properti | Fungsi | Contoh |
|---|---|---|
type | Tipe data yang diperbolehkan: string, integer, number, boolean, array, object, null | "type": "integer" |
properties | Definisi key di dalam object | "properties": { "port": {...} } |
required | Daftar key yang wajib ada | "required": ["port"] |
enum | Daftar nilai yang diperbolehkan | "enum": ["prod", "dev"] |
pattern | Regex yang harus dipenuhi string | "pattern": "^[a-z0-9-]+$" |
minimum / maximum | Batas bawah / atas angka | "minimum": 1, "maximum": 10 |
items | Definisi elemen dalam array | "items": { "type": "string" } |
additionalProperties | Boleh/tidaknya key di luar definisi | "additionalProperties": false |
default | Nilai default (untuk dokumentasi & tooling) | "default": 80 |
Tiga di antaranya layak dibahas lebih dalam karena paling sering menimbulkan kebingungan.
Pertama, type untuk angka. JSON Schema membedakan integer (bilangan bulat) dan number (bisa desimal). Nilai YAML seperti replicas: 3 dikenali sebagai integer, tapi replicas: 3.5 akan lolos validasi number sekaligus ditolak oleh integer. Lebih licik lagi: replicas: "3" — dengan tanda kutip — adalah string, dan akan ditolak oleh "type": "integer". Inilah salah satu kesalahan paling umum, dan schema justru dibuat untuk menangkapnya.
Kedua, additionalProperties. Secara default, JSON Schema mengizinkan key tambahan di luar yang didefinisikan di properties. Jika kalian ingin chart kalian tegas — menolak key yang tidak dikenal, sehingga typo seperti replicaCountt langsung ketahuan — set "additionalProperties": false. Tapi hati-hati: ini juga berarti setiap kali kalian menambah key baru di values.yaml, schema harus di-update, atau install akan gagal. Trade-off ini wajar untuk chart internal yang ketat, tapi tidak selalu cocok untuk chart publik yang ingin fleksibel.
Ketiga, items. Untuk memvalidasi elemen array, items mendefinisikan skema tiap elemen. Untuk array sederhana seperti daftar string, { "type": "array", "items": { "type": "string" } } sudah cukup. Untuk array of objects — misalnya daftar volume atau sidecar — setiap elemen adalah object dengan properties dan required sendiri.
{
"type": "object",
"properties": {
"extraVolumes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"path": { "type": "string" }
},
"required": ["name", "path"],
"additionalProperties": false
}
}
}
}Ketika validasi gagal, Helm menghentikan operasi dan menampilkan daftar kesalahan yang lengkap. Karena validasi berjalan per-key, kalian mendapatkan semua pelanggaran sekaligus, bukan satu per satu. Ini sangat membantu: user memperbaiki semua kesalahan dalam satu iterasi, bukan bolak-balik install-gagal-install-gagal.
Error: values don't meet the specifications of the schema(s) in the following chart(s):
- my-app:
- replicaCount: Invalid type. Expected: integer, given: string
- image.tag: Pattern mismatch. Pattern: ^v?[0-9]+\.[0-9]+\.[0-9]+$, given: latest
- service.port: Less than minimum of 1. Got: 0Penting untuk dipahami: validasi ini memeriksa nilai final yang akan dipakai chart — hasil penggabungan antara values.yaml default, file override, dan --set. Jadi schema tidak hanya melindungi dari override yang salah, tapi juga dari default di values.yaml yang ternyata tidak konsisten dengan schema. Ini adalah jaring pengaman ganda.
Tip
Gunakan helm template <release> <chart> --values overrides.yaml untuk menguji apakah nilai override kalian lolos validasi schema tanpa menyentuh cluster. Ini cara tercepat untuk iterasi saat membangun chart — tidak perlu install/upgrade sungguhan.
Schema dasar cukup untuk banyak chart, tapi kasus nyata sering butuh validasi yang bergantung pada nilai lain. Di sinilah properti logika JSON Schema berperan.
oneOf, anyOf, dan allOf memungkinkan kalian menyusun kondisi kompleks:
allOf — semua sub-schema harus valid (berguna untuk menumpuk validasi).anyOf — minimal satu sub-schema valid.oneOf — tepat satu sub-schema valid (sering untuk menegakkan pilihan eksklusif).Contoh nyata: sebuah chart yang mendukung dua mode database, PostgreSQL embedded atau external. Jika database.external.enabled true, maka database.external.host dan database.external.port wajib ada. Conditional seperti ini bisa dinyatakan dengan oneOf yang menggabungkan dua kondisi:
{
"type": "object",
"properties": {
"database": {
"type": "object",
"properties": {
"embedded": { "type": "object" },
"external": {
"type": "object",
"properties": {
"enabled": { "type": "boolean" },
"host": { "type": "string" },
"port": { "type": "integer", "minimum": 1 }
}
}
},
"oneOf": [
{ "required": ["embedded"] },
{
"required": ["external"],
"properties": {
"external": {
"required": ["enabled", "host", "port"]
}
}
}
]
}
}
}Selain composition, ada properti dependencies yang membuat validasi satu field bergantung pada keberadaan field lain. Misalnya, jika ingress.enabled adalah true, field ingress.host menjadi wajib. Di JSON Schema draft-07 ini ditulis dengan blok dependencies di level object:
{
"type": "object",
"properties": {
"ingress": {
"type": "object",
"properties": {
"enabled": { "type": "boolean", "default": false },
"host": { "type": "string" }
},
"dependencies": {
"enabled": { "required": ["host"] }
}
}
}
}Perlu dicatat perbedaan konsep antara oneOf/anyOf/allOf (komposisi logis) dan dependencies (validasi kondisional antar field). oneOf menegakkan "tepat satu cabang", sementara dependencies menegakkan "jika field A ada/bernilai tertentu, maka field B harus ada". Keduanya sering dipakai bersama untuk skema chart enterprise yang kompleks.
Important
Saat menggunakan draft-2020-12 (dengan deklarasi $schema yang sesuai), perhatikan bahwa struktur untuk kondisi berubah: dependencies digantikan oleh dependentRequired dan dependentSchemas, dan $defs menggantikan definitions. Jika chart kalian memakai library validasi yang lebih baru, gunakan sintaks yang tepat untuk draft yang kalian deklarasikan.
Schema tidak hanya menolak nilai salah; ia juga memberdayakan tooling yang membuat pengalaman pengguna chart jauh lebih baik.
Pertama, pesan error yang jelas. Dibandingkan error template atau error Kubernetes yang cryptic, pesan validasi schema memberi tahu persis key mana yang bermasalah dan harapannya apa. Ini memangkas waktu debugging dari menit ke detik.
Kedua, dokumentasi otomatis. Properti description di setiap field schema bisa menjadi sumber dokumentasi yang dibaca IDE. Alih-alih menggali values.yaml dan komentar yang tersebar, pengguna bisa melihat penjelasan field langsung saat mengetik.
Ketiga, autocompletion IDE. Karena schema adalah standar terbuka, editor seperti VS Code (melalui ekstensi YAML) bisa membaca values.schema.json dan memberikan autocompletion untuk setiap key yang valid, termasuk nilai yang diperbolehkan oleh enum. Ini secara dramatis mengurangi typo dan kesalahan penulisan — pengguna tidak perlu menghafal struktur values.yaml.
replicaCount: 3
image:
repository: nginx
tag: 1.27.0
service:
port: 80Selaras dengan key yang sama, schema bisa memberikan deskripsi per field:
{
"type": "object",
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1,
"description": "Jumlah replica aplikasi. Minimum 1, tidak boleh string."
},
"service": {
"type": "object",
"properties": {
"port": {
"type": "integer",
"minimum": 1,
"maximum": 65535,
"description": "Port Service yang di-expose."
}
}
}
}
}Dengan begini, satu file schema berfungsi ganda: sebagai penegak kontrak saat install dan sebagai basis dokumentasi interaktif di editor.
Seperti semua tool, JSON Schema punya jebakan yang bisa bikin pengalaman buruk jika tidak dipahami. Berikut yang paling sering ditemui.
Pitfall pertama: schema lebih ketat daripada values.yaml default. Jika schema menetapkan "required": ["replicaCount"] tapi values.yaml tidak punya key tersebut, helm install langsung gagal meski user tidak melakukan apa-apa. Selalu pastikan setiap key yang di-required ada di values.yaml, dan setiap default sudah lolos schema. Cara tercepat memastikan ini: jalankan helm template dengan values.yaml murni (tanpa override) — jika ini gagal, chart kalian rusak sejak awal.
Pitfall kedua: additionalProperties: false yang terlalu ketat di level atas. Untuk chart besar dengan puluhan key, menutup seluruh schema dengan additionalProperties: false di root berarti setiap penambahan key memaksa update schema. Strategi yang lebih baik: terapkan additionalProperties: false hanya pada object kecil yang nilai key-nya benar-benar terbatas, biarkan level atas tetap terbuka.
Pitfall ketiga: lupa bahwa YAML secara teknis bisa menahan key non-string. JSON Schema menganggap key object sebagai string, jadi tidak masalah. Tapi pastikan nilai yang kalian beri --set cocok dengan tipe di schema. --set replicaCount=3 menghasilkan integer, sementara --set replicaCount="3" menghasilkan string. Konsistensi tipe antara CLI override dan schema adalah tanggung jawab user, dan schema lah yang menegakkannya.
Pitfall keempat: tidak menguji schema. Schema adalah kode, dan kode perlu diuji. Gunakan helm template dengan berbagai kombinasi nilai — valid dan invalid — untuk memastikan schema menolak yang salah dan menerima yang benar. Beberapa tim bahkan menulis test khusus untuk schema, misalnya dengan helm-unittest yang akan kita bahas di episode 14 berikutnya.
Note
Mulailah dengan schema yang ringkas: validasi tipe data untuk semua key penting, required untuk key wajib, dan enum untuk nilai yang pilihannya terbatas. Perluas ke conditional dan composition setelah chart kalian makin kompleks. Schema yang terlalu ambisius sejak awal justru menyulitkan iterasi.
Pada episode ini kita membahas bagaimana values.schema.json mengubah nilai chart dari "bebas nilai" menjadi "kontrak yang terjamin": struktur dasar schema, properti validasi seperti type, required, enum, pattern, minimum/maximum, items, dan additionalProperties; validasi otomatis yang berjalan sebelum template dirender dengan pesan error yang jelas; schema tingkat lanjut dengan oneOf/anyOf/allOf dan dependencies untuk validasi kondisional; hingga manfaat nyata bagi pengguna chart berupa dokumentasi dan autocompletion IDE. Yang terpenting, kalian sekarang paham bahwa schema adalah garis pertahanan pertama yang mencegah kesalahan konfigurasi sampai ke cluster.
Di episode 14 selanjutnya kita akan membahas testing chart secara sistematis — dari helm test, unit test rendering template dengan helm-unittest, validasi manifest dengan kubeconform, hingga integrasi ke CI dengan chart-testing. Kombinasi schema (validasi nilai) dan testing (validasi output) inilah yang membuat chart kalian layak dipublikasikan dan dipercaya banyak tim. Pastikan tetap semangat!