Satu perubahan konfigurasi kecil — menaikkan worker_processes, mengganti port, menambah satu baris di sshd_config — adalah pekerjaan tiga menit di satu server. Kalikan lima puluh server, dan pekerjaan itu berubah menjadi sore yang hilang plus jaminan pasti ada server nomor 37 yang terlupa atau salah ketik. Configuration management menyelesaikannya dengan membalik arah kerja: alih-alih mengetik perintah di tiap mesin, kita menuliskan keadaan akhir yang benar, lalu mesin yang berjalan menyeret dirinya menuju keadaan itu. Chapter ini membedah konsep intinya — state akhir, idempotensi, konvergensi — dan membuktikannya dengan skrip bash yang bisa kita jalankan dan uji ulang di container latihan.
Masalah Lima Puluh Server #
Bayangkan kita mengelola lima puluh server web dan tim memutuskan worker_processes dinaikkan dari 1 ke 2. Jalan manualnya: ssh ke tiap mesin, vim berkasnya, restart nginx, lalu catat mana yang sudah. Tiga masalah muncul dari cara ini. Pertama, pekerjaannya membosankan sehingga mudah ceroboh — server nomor 37 mendapat worker_processs dan nobody knows. Kedua, tidak ada jejak: begitu selesai, tidak ada yang bisa menjawab “server mana saja yang sudah diubah, kapan, oleh siapa”. Ketiga, server yang terlanjur berbeda-beda akan semakin berbeda — yang di administrasi dunia nyata disebut configuration drift — sampai tiap mesin menjadi snowflake yang perlu perlakuan khusus.
Configuration drift juga datang dari arah yang tidak terduga: admin yang sedang buru-buru mengubah satu file lewat SSH “cuma sebentar”, hotfix tengah malam yang tak pernah dirapikan, atau server yang terlewat dari satu putaran update. Drift kecil yang dibiarkan lama-lama membuat armada server kita diam-diam terbelah menjadi banyak varian konfigurasi.
Deklarasikan State Akhir, Jalankan Berkali-kali #
Jalan keluarnya sudah kita kenali di Chapter Infrastructure Automation : berhenti menuliskan langkah, mulai menuliskan hasil. Sebuah manifest menyatakan “berkas ini harus berisi teks ini”, dan sebuah program aplikator membandingkan manifest dengan keadaan nyata lalu melakukan apa pun yang diperlukan — membuat berkas yang hilang, memperbaiki yang berubah, membiarkan yang sudah benar. Dua sifat penting lahir dari pola ini:
- Idempoten: menjalankan penerapan yang sama berkali-kali menghasilkan keadaan akhir yang sama — lari kedua tidak mengubah apa-apa lagi.
- Konvergen: sistem yang menyimpang ditarik kembali ke keadaan yang dideklarasikan setiap kali penerapan dijalankan.
Kedua kata itu bukan klaim pemasaran; keduanya bisa diuji. Dan karena itulah latihan chapter ini berbeda dari bab-bab sebelumnya — kita akan menjalankan buktinya sendiri.
Idempotensi dalam Praktik: kelola-konfigurasi.sh #
Bundle chapter ini membawa dua berkas: manifest sederhana berformat tujuan|isi, dan skrip kelola-konfigurasi.sh yang menerapkannya. Nama foldernya disederhanakan (etc-nginx/, bukan /etc/nginx/) karena container latihan tidak punya akses root — polanya sama, hanya skalanya yang dikecilkan. Berikut isi manifestnya:
cat manifest.confOutput yang Dihasilkan:
# format: tujuan|isi yang diharapkan (satu baris)
etc-nginx/umum.conf|worker_processes 2;
etc-nginx/situs.conf|listen 80; server_name contoh.example.com;
bin/lapor-harian.sh|echo laporan harian serverBaris pertama adalah komentar yang dijelaskan formatnya; tiga baris berikutnya menyatakan tiga berkas yang harus ada beserta isinya — dua konfigurasi nginx dan satu skrip laporan harian. Sekarang kita jalankan penerapannya untuk pertama kali pada direktori yang masih kosong:
bash kelola-konfigurasi.sh manifest.confOutput yang Dihasilkan:
changed etc-nginx/umum.conf
changed etc-nginx/situs.conf
changed bin/lapor-harian.sh
== REKAP: total=3 changed=3 ok=0 ==Ketiga berkas belum ada, jadi semuanya berstatus changed — persis laporan task di tools sungguhan. Mari kita bedah skripnya bagian demi bagian:
if [ $# -ne 1 ]: gerbang argumen — tanpa path manifest, skrip hanya mencetak cara pakai dan berhenti dengan sukses.while IFS='|' read -r tujuan isi: membaca manifest baris demi baris, membelah pada tanda|sehingga spasi di dalam isi berkas tetap utuh —IFSlokal seperti yang kita latih di Chapter Bash Basics .case "$tujuan" in ''|'#'*) continue: melompati baris kosong dan baris komentar manifest.[ -f ... ] && [ "$(cat ...)" = "$isi" ]: inti idempotensi — berkas dianggap selesai hanya bila ada dan isinya persis sama;$(cat ...)otomatis membuang newline di akhir berkas agar perbandingannya adil.mkdir -p+printf '%s\n': berkas ditulis hanya di cabangchanged— cabangoktidak menyentuh disk sama sekali.
Sekarang ujian sesungguhnya. Idempotensi berarti lari kedua dan ketiga harus menghasilkan output yang identik — bukan sekadar “tampak sama”. Blok berikut membuang lari pertama ke /dev/null (sandbox selalu mulai kosong, jadi penerapan pertama harus dibuang dulu), lalu menangkap dua lari berikutnya dan membandingkannya:
bash kelola-konfigurasi.sh manifest.conf > /dev/null
bash kelola-konfigurasi.sh manifest.conf > lari2.txt
bash kelola-konfigurasi.sh manifest.conf > lari3.txt
diff lari2.txt lari3.txt && echo "lari kedua dan ketiga: output identik"
cat lari2.txtOutput yang Dihasilkan:
lari kedua dan ketiga: output identik
ok etc-nginx/umum.conf
ok etc-nginx/situs.conf
ok bin/lapor-harian.sh
== REKAP: total=3 changed=0 ok=3 ==diff tidak mencetak apa pun karena kedua file sama persis, dan && menjadikan “output identik” sebagai pernyataan yang teruji — bukan kebetulan yang kita harapkan. REKAP changed=0 ok=3 menutup buktinya: penerapan ulang tidak mengubah apa pun. Inilah yang membuat configuration management aman dijadwalkan — boleh dijalankan tiap jam tanpa efek samping.
Arsitektur Tool: Agent, Agentless, Push, Pull #
Bagaimana definisi itu sampai ke lima puluh server? Ada dua sekolah:
| Model | Cara kerja | Kelebihan | Harga yang dibayar |
|---|---|---|---|
| Agent (pull) | daemon di tiap server menarik konfigurasi dari server pusat secara berkala | server pusat tahu kondisi terkini; cocok skala ribuan | harus memasang dan mengelola daemon + infrastruktur pusat |
| Agentless (push) | mesin kendali menjalankan SSH ke tiap server saat dibutuhkan | tanpa daemon, mulai cepat, permintaan sesuai kebutuhan | butuh akses SSH ke mana-mana; skala besar lebih lambat |
Model pull memberi server otonomi untuk menyembuhkan dirinya — daemon menarik konfigurasi bahkan saat tidak ada yang menjalankan apa pun. Model push memberi admin kendali penuh atas kapan perubahan menyentuh produksi: tidak ada yang berubah sampai kita menekan enter. Puppet, Chef, dan Salt lahir dari sekolah agent; Ansible membuktikan agentless cukup untuk sebagian besar kebutuhan.
Konfigurasi sebagai Kode #
Manifest yang kita buat hanyalah teks — dan di situlah kekuatannya. Disimpan di Git, setiap perubahan konfigurasi server melewati alur yang sama dengan kode aplikasi: branch, review oleh rekan, pengujian di server staging, lalu peleburan. Ketika perubahan menimbulkan masalah di produksi, git revert mengembalikan definisi dan penerapan berikutnya mengembalikan server — rollback yang sebenarnya, bukan “coba ingat apa yang kemarin diubah”.
Dua kebiasaan menutup lingkaran ini. Pertama, uji dulu: perubahan besar diuji di satu server staging sebelum seluruh armada — bedakan dengan flag --check bila tool menyediakannya. Kedua, jaga kualitas skrip: aplikator buatan sendiri seperti kelola-konfigurasi.sh tetap skrip bash yang layak diperiksa shellcheck seperti di Chapter Shellcheck dan Script Quality
.
Peta Tool Configuration Management #
Empat nama mendominasi lanskap ini, dan tabel berikut memetakan posisinya:
| Tool | Model | Format definisi | Ciri khas |
|---|---|---|---|
| Ansible | agentless, push | YAML | tanpa daemon, mulai dari SSH saja — default dunia Linux |
| Puppet | agent, pull | DSL sendiri | matang, cocok armada besar dengan banyak tim |
| Chef | agent, pull | Ruby | “recipe” berorientasi programmer |
| Salt | agent (bisa SSH), push/pull | YAML | event-driven, eksekusi paralel cepat |
Ketiganya yang ber-agent lahir lebih dulu dan unggul di skala ribuan server; Ansible datang belakangan dengan tarikan sederhananya: tidak ada yang perlu dipasang di server selain SSH dan Python. Untuk sisa section ini kita memilih satu tool dan membedahnya sampai ke porosnya — inventaris, playbook, dan modulnya. Chapter berikutnya: Ansible .
Referensi lanjut: shellcheck untuk menjaga kualitas aplikator buatan sendiri, serta Debian Administrator’s Handbook untuk praktik mengelola armada server Debian.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
kelola-konfigurasi.sh
Unduh berkas#!/usr/bin/env bash
# kelola-konfigurasi.sh — terapkan manifest "tujuan|isi" secara idempoten.
# Pemakaian: bash kelola-konfigurasi.sh <manifest>
set -u
if [ $# -ne 1 ]; then
echo "Pemakaian: bash kelola-konfigurasi.sh <manifest>"
exit 0
fi
manifest=$1
dir_manifest=$(dirname "$manifest")
berubah=0
total=0
while IFS='|' read -r tujuan isi; do
case "$tujuan" in ''|'#'*) continue ;; esac
total=$((total + 1))
if [ -f "$dir_manifest/$tujuan" ] && [ "$(cat "$dir_manifest/$tujuan")" = "$isi" ]; then
printf 'ok %s\n' "$tujuan"
else
mkdir -p "$(dirname "$dir_manifest/$tujuan")"
printf '%s\n' "$isi" > "$dir_manifest/$tujuan"
printf 'changed %s\n' "$tujuan"
berubah=$((berubah + 1))
fi
done < "$manifest"
echo "== REKAP: total=$total changed=$berubah ok=$((total - berubah)) =="