Di episode ini kita akan membedah node attributes: lima level attribute dan urutan precedence-nya, cara kerja Ohai mengumpulkan fakta sistem, serta cara membaca attribute di dalam recipe.

Di episode 4 kalian sudah menguasai resource dan recipe — bahasa inti untuk mendeskripsikan apa yang diinginkan. Namun ada pertanyaan yang pasti muncul begitu recipe kalian mulai kompleks: bagaimana cara membuat satu cookbook berperilaku berbeda di node yang berbeda? Jawabannya ada di attributes.
Episode 5 ini membedah dua konsep yang sering dianggap sulit padahal justru sangat fungsional: node attributes (data yang menggambarkan node dan mendorong perilaku recipe) dan Ohai (mesin yang mengumpulkan data tersebut). Kita akan membahas lima level attribute beserta urutan precedence-nya — dari mana nilainya berasal dan siapa yang menang ketika terjadi konflik — serta cara membaca attribute di dalam recipe.
Attribute adalah pasangan key-value yang melekat pada node. Bayangkan attribute sebagai "KTP" sebuah node: sistem operasi apa, berapa memory-nya, IP address apa, hostname apa, dan pengaturan apa yang harus dipakai cookbook.
Attribute mengalir dari banyak sumber: Ohai (otomatis), attribute file di cookbook, environment, role, dan atribut yang di-set langsung di node. Pertanyaannya kemudian: jika banyak sumber menetapkan nilai yang sama, siapa yang menang? Inilah yang diatur oleh precedence.
Chef mengenal beberapa level attribute. Di level awal series ini, fokus pada lima level utama berikut, diurutkan dari prioritas terendah ke tertinggi:
| Level | Prioritas | Dari mana | Contoh |
|---|---|---|---|
default | 1 (terendah) | Attribute file cookbook | default['nginx']['port'] = 80 |
force_default | 2 | Attribute file / node | memaksa menimpa default |
normal | 3 | Di-set ke node | knife node edit |
override | 4 | Attribute file / role / env | override['nginx']['port'] = 8080 |
automatic | 5 (tertinggi) | Ohai saja | automatic['ipaddress'] |
Aturan emasnya: level dengan prioritas lebih tinggi menimpa level yang lebih rendah. automatic (Ohai) selalu menang, default selalu kalah.
1. default (cookbook attribute) -- paling mudah ditimpa
2. force_default (memaksa nilai default)
3. normal (di-set langsung di node)
4. override (role / environment / cookbook)
5. automatic (Ohai) -- tidak bisa ditimpa cookbookTip
Aturan praktis: gunakan default untuk nilai bawaan di cookbook, override di environment untuk perbedaan antar tahap (dev vs prod), dan biarkan automatic (Ohai) bekerja sendiri. Jarang sekali kalian perlu force_default atau normal di awal belajar.
Untuk memahami precedence, kita harus tahu dari mana tiap level datang:
default — dideklarasikan di attributes/default.rb cookbook.force_default — juga dari attribute file, tapi lebih diprioritaskan.normal — disimpan di node object di server, biasanya via knife node edit node-01.override — dari attribute file cookbook, role, atau environment.automatic — sepenuhnya dari Ohai, tidak pernah ditulis manual.Contoh deklarasi di attribute file cookbook:
default['nginx']['port'] = 80
default['nginx']['worker_processes'] = 2
default['nginx']['server_name'] = 'example.com'Ohai adalah tool yang dijalankan chef-client di fase pertama (ingat episode 2) untuk mengumpulkan fakta node menjadi attribute automatic. Ohai bekerja melalui plugin — setiap plugin bertanggung jawab atas satu area data.
Plugin Ohai yang paling sering dipakai:
| Plugin | Data yang dikumpulkan |
|---|---|
os | OS, platform, platform family, versi |
memory | Total dan memory yang tersedia |
network | Interface, IP address, gateway |
cpu | Arsitektur, jumlah core |
hostname | Hostname dan FQDN |
disk | Partisi dan ruang disk |
languages | Versi runtime (Ruby, Python, dll) |
platform: ubuntu
platform_version: 22.04
memory.total: 3.82GB
cpu.total: 2
hostname: node-01
network.interfaces.eth0.addresses: 10.0.0.11Untuk melihat data Ohai secara langsung di node:
ohai platform
ohai memory
ohai network/ipaddressNote
Ohai menyimpan datanya sebagai attribute automatic. Karena automatic punya precedence tertinggi, data Ohai tidak bisa ditimpa cookbook — dan memang seharusnya begitu. OS node adalah kenyataan, bukan keinginan.
Jika data bawaan belum cukup, kita bisa menulis plugin Ohai sendiri. Plugin ditulis dalam Ruby dan ditaruh di ohai/plugins/ cookbook.
Ohai.plugin(:AppVersion) do
provides 'app_version'
collect_data(:linux) do
app_version(
shell_out('cat /opt/app/version.txt').stdout.strip
) if File.exist?('/opt/app/version.txt')
end
endPlugin di atas membaca versi aplikasi dari sebuah file dan memublikasikannya sebagai attribute app_version. Setelah di-load, recipe bisa membacanya seperti attribute biasa.
Sekarang bagian praktisnya: bagaimana recipe memakai attribute. Ada dua cara — membaca attribute node, dan membaca attribute dari cookbook.
# Attribute automatic dari Ohai
log node['platform'] do
level :info
end
# Kombinasi untuk keputusan bercabang
if node['platform_family'] == 'debian'
package 'nginx' do
action :install
end
end
# Attribute default dari cookbook sendiri
log "Port nginx: #{node['nginx']['port']}" do
level :info
endWarning
Perhatikan penggunaan tanda kutip: attribute diakses dengan bracket dan key string, contoh node['nginx']['port']. Pastikan key yang kalian baca sudah dideklarasikan di attribute file cookbook — membaca key yang tidak ada mengembalikan nil dan bisa membuat recipe berperilaku tidak terduga.
Mari gabungkan semuanya. Recipe berikut menggunakan attribute Ohai untuk menyesuaikan package dan service name sesuai platform:
webserver_package = node['platform_family'] == 'debian' ? 'nginx' : 'httpd'
package webserver_package do
action :install
end
service webserver_package do
action [:enable, :start]
end
# Gunakan attribute default cookbook untuk konfigurasi
template '/etc/nginx/conf.d/server.conf' do
source 'server.conf.erb'
variables(
server_name: node['nginx']['server_name'],
port: node['nginx']['port']
)
notifies :restart, "service[#{webserver_package}]"
endknife node edit node-01{
"name": "node-01",
"normal": {
"nginx": {
"port": 8080
}
}
}Tip
Dengan attribute di atas node (normal), cookbook yang sama bisa dipakai di node yang berbeda dengan perilaku berbeda — node-01 memakai port 8080, node-02 tetap 80. Inilah kekuatan "satu kode, banyak konfigurasi" yang menjadi inti infrastructure as code.
Untuk debugging, kita bisa melihat seluruh attribute sebuah node sekaligus:
knife node show node-01 --format jsonDi episode 5 ini kita sudah membedah dua fondasi data Chef: node attributes beserta lima level dan precedence-nya (default, force_default, normal, override, automatic), cara Ohai dan plugin-pluginnya mengumpulkan fakta sistem, serta cara membaca attribute di dalam recipe untuk membuat cookbook yang adaptif.
Inti yang harus dibawa pulang:
automatic.Dengan attributes dan Ohai, cookbook kalian kini adaptif terhadap perbedaan node. Di episode 6 selanjutnya, kita akan membahas cookbook & run list — struktur lengkap direktori cookbook (recipes, attributes, templates, files, libraries, metadata.rb), cara menyusun run_list per node, serta peran roles dan environments untuk pengelompokan node.