Pelajari cara membuat template ERB yang merender file konfigurasi berdasarkan atribut node, penggunaan resource template dengan variabel, serta cara menyimpan data terstruktur di server menggunakan data bags, termasuk encrypted data bag dan chef-vault untuk mengamankan secret seperti password dan kunci API.

Di episode 6 kalian sudah mengenal anatomi cookbook, run list, roles, dan environments. Kalian memahami bagaimana recipes/ menjadi entry point, bagaimana metadata.rb menyimpan identitas cookbook, serta bagaimana run list menentukan urutan eksekusi recipe di setiap node. Salah satu direktori yang sudah disinggung adalah templates/, tempat file konfigurasi berbasis ERB disimpan.
Sekarang pertanyaannya: bagaimana sebuah file konfigurasi seperti /etc/nginx/nginx.conf bisa berbeda-beda di tiap node tanpa menulis ulang? Jawabannya ada di template ERB yang dirender dengan variabel node. Kemudian, bagaimana menyimpan data terstruktur seperti daftar pengguna atau secret di server agar dipakai banyak cookbook? Jawabannya ada di data bags.
Episode 7 ini akan membahas cara kerja template ERB dan resource template, lalu dilanjutkan dengan data bags biasa, encrypted data bag untuk secret, serta chef-vault untuk mengelola secret di banyak node.
Template ERB adalah file berisi campuran teks statis dan tag Ruby. Saat chef-client menjalankan resource template, file ini dirender terlebih dahulu, baru hasilnya ditulis ke target path. Ada dua bentuk tag ERB: <%= node['hostname'] %> yang memasukkan hasil ekspresi Ruby, dan <% if ... %> yang menjalankan logika kondisional tanpa mencetak apapun.
File template disimpan di direktori templates/default/ di dalam cookbook. Nama file boleh sama dengan target, atau berbeda jika kalian menggunakan properti source. Contoh berikut adalah template untuk Nginx:
user www-data;
worker_processes <%= node['nginx']['worker_processes'] %>;
pid /run/nginx.pid;
events {
worker_connections <%= node['nginx']['worker_connections'] %>;
}
http {
sendfile on;
server_tokens off;
server {
listen <%= node['nginx']['port'] %>;
server_name <%= node['hostname'] %>;
root /var/www/html;
}
}Setiap <%= ... %> di dalam template diganti dengan nilai atribut node saat render, sehingga satu template bisa menghasilkan konfigurasi berbeda untuk node development yang kecil dan node production yang besar.
Untuk memakai template, deklarasikan resource template '/etc/nginx/nginx.conf' do di dalam recipe. Resource ini butuh properti path sebagai lokasi target, source sebagai nama file di folder templates, dan variables untuk menyalurkan nilai tambahan selain atribut node:
template '/etc/nginx/nginx.conf' do
source 'nginx.conf.erb'
owner 'root'
group 'root'
mode '0644'
variables(
port: node['nginx']['port'],
server_name: node['hostname']
)
notifies :reload, 'service[nginx]'
end
service 'nginx' do
action [:enable, :start]
endProperti mode '0644' menetapkan permission file hasil render. notifies :reload, 'service[nginx]' memicu reload Nginx hanya ketika isi file benar-benar berubah, sehingga proses tidak berhenti saat tidak ada perubahan konfigurasi.
Tip
Di dalam file .erb, tag <%= node['hostname'] %> adalah contoh inline hint ala Chef: tanda kutip ganda di dalam kurung siku menunjuk pada atribut node. Pastikan nama atribut persis sama dengan yang didefinisikan di direktori attributes/, karena salah eja akan menghasilkan nilai kosong.
Data bag adalah struktur data global yang disimpan di chef-server dan bisa dibaca oleh cookbook mana pun. Data bag berisi item berbentuk JSON. Contoh penggunaannya adalah daftar aplikasi, daftar akun, atau konfigurasi bersama yang tidak cocok disimpan sebagai atribut.
Buat data bag dari workstation dengan knife data bag create apps, lalu upload itemnya:
knife data bag create apps
knife data bag create apps order_service
knife data bag from file apps order_service.jsonIsi file item order_service.json terlihat seperti berikut:
{
"id": "order_service",
"port": 8080,
"replicas": 3,
"repository": "git@github.com:org/order-service.git"
}Untuk membaca data bag di dalam recipe, gunakan helper data_bag_item('apps', 'order_service') yang mengembalikan hash berisi field item, lalu salurkan nilainya ke template atau resource lain. Jika ingin mengambil semua item sekaligus, data_bag('apps') mengembalikan array berisi id semua item dan pola ini berguna untuk membuat resource secara berulang.
Note
Data bag biasa disimpan dalam teks terbuka di server. Data tersebut hanya cocok untuk informasi non-sensitif seperti daftar aplikasi atau konfigurasi publik. Untuk password, kunci API, atau token, gunakan encrypted data bag atau chef-vault.
Encrypted data bag menyimpan item dalam bentuk terenkripsi. Chef mengenkripsi data dengan secret key menggunakan algoritma AES-256. Untuk membuka item, secret key yang sama harus tersedia di node saat chef-client berjalan.
Buat secret key, simpan dengan aman, lalu buat data bag dengan opsi --secret-file:
openssl rand -base64 512 > /etc/chef/encrypted_data_bag_secret
knife data bag create secrets --secret-file /etc/chef/encrypted_data_bag_secret
knife data bag from file secrets db_password.json --secret-file /etc/chef/encrypted_data_bag_secretIsi db_password.json adalah JSON biasa, tetapi yang tersimpan di server sudah terenkripsi. Di dalam recipe, pembacaannya mirip data bag biasa karena chef-client otomatis memakai secret file yang didaftarkan, lalu hasilnya disalurkan ke template dengan properti sensitive true supaya password tidak bocor lewat log chef-client saat mode debug.
Warning
Secret key adalah satu-satunya kunci untuk membuka data terenkripsi. Jika file ini hilang, seluruh item dalam encrypted data bag tidak akan bisa dibaca. Simpan salinannya di tempat aman terpisah dan jangan pernah commit ke repository Git.
Chef-vault menyelesaikan kelemahan utama encrypted data bag: mendistribusikan secret key ke setiap node. Dengan chef-vault, secret dienkripsi dengan kunci publik milik node yang diizinkan membaca item, dan node hanya bisa membuka vault jika ia terdaftar sebagai klien di chef-server.
Instal plugin di workstation, lalu buat item vault:
chef gem install chef-vault
chef vault create aws api_key -S 'role:app_server' -J data_bags/vault/aws_api_key.jsonPerintah di atas menandai node dengan role app_server sebagai anggota yang boleh membaca item aws_api_key di vault aws. Baca isi vault dari dalam recipe dengan helper chef_vault_item('aws', 'api_key') yang mengembalikan hash berisi kredensial, lalu gunakan nilainya untuk template dengan sensitive true. Chef-vault otomatis mendistribusikan kunci ke node anggota, sehingga kalian tidak perlu menyalin secret key secara manual dan pencabutan akses cukup dengan menghapus node dari daftar anggota vault.
Tabel berikut membantu kalian memilih metode yang tepat:
| Aspek | Data Bag Biasa | Encrypted Data Bag | Chef-Vault |
|---|---|---|---|
| Tingkat keamanan | Teks terbuka | AES-256 | Enkripsi per-node |
| Distribusi kunci | Tidak ada | Manual ke tiap node | Otomatis ke node anggota |
| Pencabutan akses | Tidak ada | Tidak ada | Hapus dari anggota vault |
| Cocok untuk | Data publik | Secret statis | Secret yang dibaca banyak node |
Important
Urutan prioritas yang disarankan: gunakan data bag biasa untuk data non-sensitif, encrypted data bag untuk secret yang dibaca satu atau dua node, dan chef-vault untuk secret yang harus dibaca banyak node dengan siklus hidup dinamis. Jangan pernah menyimpan password atau token dalam bentuk teks terbuka.
Pada episode 7 ini kalian sudah belajar cara membuat file konfigurasi yang dinamis dengan template ERB dan resource template, lengkap dengan properti source, mode, dan variables. Kalian juga sudah memahami tiga tingkatan penyimpanan data di server: data bag biasa untuk data terbuka, encrypted data bag untuk secret yang dienkripsi dengan secret key, serta chef-vault yang mendistribusikan akses secara otomatis ke node yang berhak.
Inti yang harus dibawa pulang:
<%= node['...'] %> dan bisa dikondisikan dengan tag <% if ... %>.mode, owner, dan notifies untuk reload service.data_bag_item di dalam recipe.Di episode 8 berikutnya kita akan berlatih mengendalikan seluruh infrastruktur dari workstation menggunakan Knife & Chef CLI. Kalian akan menguasai knife node list, knife cookbook upload, knife data bag create, knife ssh, knife bootstrap, serta pengelolaan environment dan pembekuan versi cookbook. Sampai jumpa di episode berikutnya.