Dari empat tool configuration management di Chapter Configuration Management
, satu nama menjadi pilihan bawaan administrator Linux: Ansible, dengan janji yang sederhana tapi memikat — tanpa agent, tanpa daemon, cukup SSH dan Python yang sudah ada di hampir semua server. Seluruh kecerdasan berada di mesin kendali (control node): di situlah inventory, playbook, dan modul digabung menjadi perintah yang didorong ke banyak server sekaligus. Chapter ini membedah ketiga poros itu satu per satu sampai ke format berkasnya. Paket ansible tidak terpasang di container latihan, jadi kita menulis berkas inventory dan playbook sungguhan, lalu mensimulasikan mesin eksekusinya dengan skrip bash yang deterministik.
Agentless: Cukup SSH dan Python #
Ansible bekerja lewat jalur yang sudah kita kuasai: SSH dari Chapter Remote Shell . Mesin kendali membaca inventory, membuka koneksi SSH ke setiap host, lalu mengirimkan modul — potongan kode Python kecil — untuk dijalankan di sana. Hasilnya dikembalikan sebagai JSON, dirangkum menjadi laporan, dan koneksi ditutup; tidak ada yang tertinggal di server. Bandingkan dengan Puppet atau Chef yang memasang daemon permanen di setiap mesin: dengan Ansible, server yang sedang tidak dikelola tidak membuka satu port ekstra pun.
Konsekuensi arsitektur ini: autentikasi SSH adalah kunci kerajaan. Kunci publik yang dikelola lewat Chapter SSH Keys dan Agent
harus terpasang di setiap host, dan user yang dipakai harus punya hak sudo untuk task yang menuntutnya — persis pola sudo yang kita kelola di awal Course.
Inventory: Peta Server yang Dikelola #
Sebelum bisa mengerjakan apa pun, Ansible perlu tahu server mana saja yang dikelolanya. Jawabannya adalah inventory — daftar host berformat INI yang dikelompokkan sesuai perannya:
cat > inventory.ini << 'EOF'
[web]
web-jakarta ansible_host=203.0.113.10
web-surabaya ansible_host=203.0.113.11
[database]
db-jakarta ansible_host=203.0.113.20
[produksi:children]
web
database
EOF
cat inventory.iniOutput yang Dihasilkan:
[web]
web-jakarta ansible_host=203.0.113.10
web-surabaya ansible_host=203.0.113.11
[database]
db-jakarta ansible_host=203.0.113.20
[produksi:children]
web
databaseMari kita bedah baris demi baris:
[web]: membuka grup bernamaweb— semua host di bawahnya sampai baris kosong menjadi anggotanya; playbook menargethosts: webakan menyentuh keduanya.web-jakarta ansible_host=203.0.113.10: nama host beserta variabelansible_hostyang memberi tahu alamat aslinya — nama boleh human-friendly, alamat tetap presisi.[database]: grup kedua; server database dipisahkan karena playbooknya berbeda.[produksi:children]: grup dari grup —produksiberisi seluruh anggotawebdandatabase, sehingga satu playbook bisa menarget keduanya sekaligus bila perlu.
Playbook: Resep dalam YAML #
Playbook mendeskripsikan keadaan akhir yang kita inginkan dalam YAML — format yang sama dengan user-data cloud-init di Chapter cloud-init . Berikut playbook yang memasang nginx, menyebarkan konfigurasi, lalu memastikan service hidup:
cat > playbook-web.yml << 'EOF'
---
- name: Pasang web server nginx
hosts: web
become: true
tasks:
- name: pastikan nginx terpasang
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: salin konfigurasi situs
ansible.builtin.copy:
src: situs.conf
dest: /etc/nginx/sites-available/default
mode: "0644"
notify: muat ulang nginx
- name: pastikan nginx berjalan
ansible.builtin.service:
name: nginx
state: started
enabled: true
handlers:
- name: muat ulang nginx
ansible.builtin.service:
name: nginx
state: reloaded
EOF
cat playbook-web.ymlOutput yang Dihasilkan:
---
- name: Pasang web server nginx
hosts: web
become: true
tasks:
- name: pastikan nginx terpasang
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: salin konfigurasi situs
ansible.builtin.copy:
src: situs.conf
dest: /etc/nginx/sites-available/default
mode: "0644"
notify: muat ulang nginx
- name: pastikan nginx berjalan
ansible.builtin.service:
name: nginx
state: started
enabled: true
handlers:
- name: muat ulang nginx
ansible.builtin.service:
name: nginx
state: reloadedStruktur inilah yang membedakan playbook dari sekadar daftar perintah. Mari kita bedah bagian demi bagiannya:
- name:/hosts: web/become: true: satu play — satuan eksekusi yang menarget grupwebdari inventory, denganbecome: truemenaikkan hak ke sudo seperti flag-bdi command line.tasks:dan tiap- name:: daftar langkah yang berurutan dari atas ke bawah;namewajib dan dibaca manusia — nantinya muncul di layar saat eksekusi.ansible.builtin.apt: ...: modul pengelola paket Debian dengan argumennamedanstate: present— “harus terpasang”, bukan “pasang sekarang”;update_cache: truesetaraapt updatedari Chapter Updating dan Upgrading System .ansible.builtin.copy: ...: menyalinsitus.confke server denganmode "0644"— pola permission dari Chapter File Permissions .notify: muat ulang nginxdanhandlers:: task copy hanya “melapor berubah” ke handler bernamamuat ulang nginx; handler berjalan di akhir play dan hanya bila ada yang berubah — service tidak direstart ketika isinya sudah sama.
Module yang Paling Sering Dipakai #
Semua pekerjaan playbook dilakukan modul — ratusan jumlahnya, tetapi segelintir menutup 90% kebutuhan harian:
| Module | Fungsi | Argumen kunci |
|---|---|---|
ansible.builtin.apt | paket di Debian/Ubuntu | name, state |
ansible.builtin.copy | menyalin berkas apa adanya | src, dest, mode |
ansible.builtin.template | merender berkas dengan variabel | src, dest |
ansible.builtin.service | mengelola service systemd | name, state, enabled |
ansible.builtin.user | membuat dan mengubah user | name, groups, shell |
ansible.builtin.command | menjalankan perintah apa adanya | cmd |
Dua baris terakhir perlu perhatian ekstra. Modul command menjalankan perintah tanpa pemeriksaan keadaan, jadi selalu melaporkan changed — idempotensinya menjadi tanggung jawab kita. Aturan praktisnya: cari modul khusus dulu (apt, user, service), dan jatuh ke command hanya bila tidak ada yang lebih spesifik.
Simulasi Eksekusi: changed di Lari Pertama, ok di Lari Kedua #
Mesin eksekusi Ansible sederhana secara konsep: untuk tiap task, bacalah keadaan server, bandingkan dengan yang diminta, lalu laporkan ok atau changed — pola idempotensi dari chapter sebelumnya. Simulasi berikut memodelkan tiga task playbook di atas dengan daftar task dan direktori state sebagai keadaan server:
cat > daftar-task.txt << 'EOF'
pastikan nginx terpasang|ansible.builtin.apt
salin konfigurasi situs|ansible.builtin.copy
pastikan nginx berjalan|ansible.builtin.service
EOF
mkdir -p state
jalankan() {
while IFS='|' read -r nama modul; do
if [ -e "state/$modul" ]; then
printf 'ok [%s]\n' "$nama"
else
printf 'changed [%s]\n' "$nama"
: > "state/$modul"
fi
done < daftar-task.txt
}
echo "== lari pertama =="
jalankan
echo "== lari kedua =="
jalankanOutput yang Dihasilkan:
== lari pertama ==
changed [pastikan nginx terpasang]
changed [salin konfigurasi situs]
changed [pastikan nginx berjalan]
== lari kedua ==
ok [pastikan nginx terpasang]
ok [salin konfigurasi situs]
ok [pastikan nginx berjalan]Mari kita bedah mekanismenya:
daftar-task.txt: daftar task playbook dalam formatnama|modul— persis tiga task yang kita tulis diplaybook-web.yml.- Direktori
state/: model keadaan server — keberadaan berkas penanda menggantikan “nginx sudah terpasang” yang sesungguhnya dibaca dari sistem. if [ -e "state/$modul" ]: keputusanokversuschanged; di Ansible sungguhan pemeriksaan ini dilakukan modul terhadap keadaan nyata, bukan penanda.- Dua pemanggilan
jalankan: lari pertama mengubah semuanya, lari kedua tidak mengubah apa pun — playbook yang sehat selalu begini.
Di layar, eksekusi nyata ditampilkan per task per host. Berikut contoh tampilan ansible-playbook untuk playbook kita di dua server:
PLAY [Pasang web server nginx] *************************************
TASK [pastikan nginx terpasang] ************************************
changed: [web-jakarta]
changed: [web-surabaya]
TASK [salin konfigurasi situs] *************************************
changed: [web-jakarta]
ok: [web-surabaya]
PLAY RECAP *********************************************************
web-jakarta : ok=3 changed=2 unreachable=0 failed=0
web-surabaya : ok=3 changed=1 unreachable=0 failed=0Baris PLAY RECAP di akhir adalah ringkasan yang dibaca cepat: changed besar berarti banyak yang bergeser, failed bukan nol berarti ada yang harus diperbaiki sebelum lari berikutnya.
Ad-hoc, Dry Run, dan Kebiasaan Aman #
Untuk pekerjaan sekali jalan tanpa playbook, ada perintah ad-hoc: satu modul, satu target. Contohnya memasang htop di seluruh grup web:
ansible web -i inventory.ini -m ansible.builtin.apt -a "name=htop state=present" -bStruktur argumennya: target web, inventory -i, modul -m, argumen modul -a, dan -b untuk sudo. Untuk playbook, padanan lengkapnya adalah ansible-playbook -i inventory.ini playbook-web.yml — tambahkan --check dan Ansible masuk mode dry run: semua task dijalankan tanpa mengubah apa pun, hanya melaporkan apa yang akan berubah.
Roles dan Vault #
Playbook yang tumbuh panjang sebaiknya dipecah menjadi role — paket task, handler, dan template yang bisa dipakai ulang. Anatominya berkonvensi ketat:
roles/
└── nginx/
├── tasks/main.yml # langkah utama role
├── handlers/main.yml # handler seperti "muat ulang nginx"
├── templates/ # berkas dengan variabel jinja2
└── defaults/main.yml # nilai bawaan yang bisa ditimpaSatu playbook tinggal memanggil roles: - nginx, dan seluruh isi folder itu terangkai — cara yang sama seperti package di dunia pemrograman: sekali ditulis, dipakai di mana saja. Untuk data rahasia seperti kunci database, Ansible menyediakan ansible-vault: perintah ini mengenkripsi berkas variabel sehingga di repository Git hanya tampil sebagai teks tersandi, dan playbook tetap bisa membacanya dengan --ask-vault-pass saat eksekusi. Prinsipnya sama dengan Chapter Secrets dan Credential Management
: rahasia tidak pernah tidur dalam plaintext.
Dengan Ansible, server kini punya resep yang bisa dijalankan ulang kapan pun — dan definisi yang sama bisa kita perlakukan seperti kode aplikasi. Chapter berikutnya, Deployment Automation , mengangkat pola itu ke ranah yang paling sering berubah: meluncurkan versi aplikasi baru ke server-server ini dengan aman, terukur, dan bisa dibatalkan.
Referensi lanjut: Arch Wiki: Ansible untuk instalasi dan pola penggunaan di berbagai distro, serta OpenSSH untuk protokol transport yang menjadi fondasi seluruh model agentless ini.