Mengelola daftar server yang dikelola Ansible melalui static dan dynamic inventory, mulai dari format INI/YAML, pengelompokkan host, host variables, hingga host pattern untuk menargetkan server secara presisi.

Setelah di episode 2 sebelumnya kita membahas arsitektur utama Ansible — mulai dari peran control node sebagai "otak" yang menjalankan semua perintah, managed nodes sebagai server-server yang dikelola, sampai alur kerja eksekusi modul Python lewat SSH — pada episode kali ini kita akan membedah salah satu komponen yang paling sering kita pegang sehari-hari: Inventory.
Kalau diibaratkan, inventory adalah buku alamat milik Ansible. Playbook dan perintah ad-hoc hanyalah "surat" yang berisi instruksi; tanpa buku alamat yang benar, surat tersebut tidak akan pernah sampai ke tujuan. Di dunia nyata, sistem yang dikelola tidak pernah hanya satu server. Bisa puluhan bahkan ribuan VM, tersebar di beberapa environment (staging, production), dengan role yang berbeda-beda (web server, database, worker). Inventory adalah peta yang memetakan semuanya, dan di episode ini kalian akan belajar membuat peta tersebut dengan benar.
Kita juga akan melihat mengapa di era cloud yang serba auto-scaling, file inventory statis saja tidak cukup — dan bagaimana dynamic inventory hadir untuk menyelesaikan masalah tersebut.
Inventory adalah file atau sumber data yang mendaftarkan semua managed nodes yang bisa dikelola Ansible. Setiap entri biasanya berisi nama host (atau IP) dan informasi koneksi seperti user SSH, port, dan kunci privat.
Important
Inventory bukan sekadar daftar nama server. Ia adalah sumber kebenaran (source of truth) tentang infrastruktur kalian. Kualitas automasi kalian — akurasi, keamanan, dan kecepatan — sangat ditentukan oleh bagaimana inventory diorganisasikan.
Ansible mendukung dua format penulisan inventory statis: INI (format warisan dari zaman awal Ansible) dan YAML (format modern yang direkomendasikan). Keduanya valid dan menghasilkan perilaku yang sama. Perbedaannya terletak pada ekspresivitas dan keterbacaan saat struktur data semakin kompleks.
[webservers]
web-01.prod.example.com
web-02.prod.example.com
web-01.staging.example.com
[dbservers]
db-01.prod.example.com
db-01.staging.example.com
[prod:children]
webservers
dbservers
[staging:children]
webservers
dbservers
[prod:vars]
ansible_user=deployDari contoh di atas, kalian bisa melihat keduanya mendefinisikan hal yang sama. Namun ada beberapa alasan mengapa YAML menjadi rekomendasi modern:
hosts, children, dan vars dalam satu blok yang rapi.Note
Format INI tetap didukung penuh untuk kompatibilitas mundur, dan banyak tutorial lama masih menggunakannya. Tidak masalah jika kalian menemukannya di dokumentasi, asalkan paham cara memetakannya ke struktur YAML.
Sistem riil hampir tidak pernah "flat". Kalian punya web server, database server, cache, dan worker — masing-masing dengan kebutuhan perlakuan berbeda. Ansible menyelesaikan ini dengan host groups, yaitu label yang memuat sekumpulan host.
Ada dua konsep kunci yang wajib dipahami:
webservers atau dbservers.Perhatikan pola hierarki pada contoh inventory di atas: grup prod dan staging adalah child groups yang menaungi webservers dan dbservers. Dengan struktur ini, satu perintah ansible prod -m ping otomatis menjangkau seluruh server di environment production — tanpa harus menyebutkan satu per satu.
Tip
Organisasikan inventory berdasarkan dua dimensi sekaligus: role (webserver/database) dan environment (prod/staging/dev). Pola ini adalah best practice yang dipakai hampir semua tim infrastruktur karena memungkinkan pattern matching yang sangat fleksibel (akan kita bahas sebentar lagi).
Setiap inventory juga memiliki dua grup implisit yang selalu ada:
all — berisi semua host yang terdaftar.ungrouped — host yang tidak masuk ke grup mana pun.Inventory yang baik tidak cukup hanya berisi nama host. Ansible perlu tahu bagaimana menghubungi server tersebut. Di sinilah peran host variables — variabel yang nilainya berlaku khusus untuk satu host.
Empat variabel koneksi yang paling sering dipakai:
| Variabel | Fungsi | Contoh Nilai |
|---|---|---|
ansible_host | Alamat IP/DNS yang dipakai SSH untuk terhubung (nama host di inventory bisa berbeda dari IP asli) | 10.0.1.10 |
ansible_user | User SSH yang dipakai untuk login | deploy |
ansible_port | Port SSH (jika bukan 22 default) | 2222 |
ansible_ssh_private_key_file | Lokasi file kunci privat SSH | ~/.ssh/id_ed25519_prod |
all:
hosts:
webserver-prod:
ansible_host: 10.0.1.10
ansible_user: deploy
ansible_port: 22
ansible_ssh_private_key_file: ~/.ssh/id_rsa_prod
webserver-staging:
ansible_host: 10.0.2.10
ansible_user: devops
ansible_ssh_private_key_file: ~/.ssh/id_rsa_staging
children:
dbservers:
hosts:
db-server:
ansible_host: 10.0.1.20
vars:
ansible_user: postgresPerhatikan contoh di atas:
webserver-prod) hanyalah nama logis. IP asli didefinisikan lewat ansible_host. Ini sangat berguna ketika IP server berubah tapi nama logis tetap — playbook kalian tidak perlu diubah.vars di level grup (ansible_user: postgres untuk semua dbservers) memungkinkan satu pengaturan berlaku untuk banyak host sekaligus. Ini contoh nyata prinsip DRY (Don't Repeat Yourself) dalam inventory.Caution
Variabel koneksi yang terkait kredensial (misalnya ansible_ssh_pass) jangan pernah ditulis hardcode di inventory yang masuk ke Git. Gunakan SSH key atau Ansible Vault (akan kita bahas di episode 14).
Setelah inventory terdefinisi, bagaimana caranya menargetkan subset host tertentu? Jawabannya adalah host patterns — bahasa untuk memilih host berdasarkan grup dan operator.
| Pattern | Makna | Contoh Penggunaan |
|---|---|---|
all | Semua host dalam inventory | ansible all -m ping |
webservers | Semua host dalam grup webservers | ansible webservers -m ping |
web-01.prod.example.com | Satu host spesifik berdasarkan nama | ansible web-01.prod.example.com -m ping |
webservers:dbservers | Union — host yang berada di salah satu grup | ansible 'webservers:dbservers' -m ping |
webservers:&staging | Intersection — host yang berada di keduanya (web server yang juga staging) | ansible 'webservers:&staging' -m ping |
webservers:!production | Exclusion — host di webservers tapi bukan di production | ansible 'webservers:!production' -m ping |
Tip
Untuk pattern yang mengandung karakter :, &, atau !, wajib dibungkus dengan tanda kutip di shell. Tanpa tanda kutip, shell bisa menafsirkannya sebagai redirect atau operator lain — salah satu kesalahan paling sering di dunia nyata.
Contoh kombinasi praktis yang sangat berguna dalam operasional harian — misalnya ingin menargetkan semua web server di production kecuali satu yang sedang bermasalah:
ansible 'webservers:&production:!web-02.prod.example.com' -m pingansible-inventorySemakin besar infrastruktur, semakin mudah salah menulis inventory. Untungnya Ansible menyediakan utilitas ansible-inventory untuk memvalidasi dan mengintrospeksi struktur inventory:
ansible-inventory -i inventory.yml --graphBentuk --graph memperlihatkan hierarki grup dengan sangat jelas. Kalau kalian butuh detail variabel per host, gunakan --list (bisa dikombinasikan dengan --yaml agar output lebih terbaca):
ansible-inventory -i inventory.yml --list --yamlPerintah lain yang sering dipakai untuk validasi cepat:
ansible all -i inventory.yml --list-hostsTip
Biasakan menjalankan ansible-inventory --graph setiap kali mengubah struktur inventory. Kesalahan hierarki jauh lebih murah ditemukan lewat graph daripada lewat error saat playbook berjalan di tengah jam sibuk.
Semua contoh di atas adalah static inventory — data ditulis manual dalam file. Ini cukup selama jumlah server stabil dan dikenal sebelumnya. Tetapi bagaimana di era cloud auto-scaling?
Bayangkan sebuah Auto Scaling Group di AWS yang bisa menambah 5 instance EC2 di pagi hari saat traffic naik dan menguranginya di malam hari. Mengikuti perubahan itu dengan menulis inventory manual adalah pekerjaan yang mustahil, lambat, dan rawan salah. Inilah kenapa dynamic inventory lahir.
Note
Dynamic inventory adalah inventory yang datanya tidak ditulis manual, melainkan di-generate otomatis setiap kali Ansible butuh — biasanya dengan bertanya langsung ke API cloud provider (AWS, GCP, Azure) atau ke sistem lain seperti CMDB.
Mekanismenya sederhana: alih-alih menunjuk ke file statis, data inventory dinamis diambil saat eksekusi berlangsung. Ini membuat daftar server selalu up-to-date mengikuti kondisi nyata di cloud — persis seperti menghubungi directory service alih-alih mengandalkan kartu alamat lama.
aws_ec2 dan gcp_computeDi Ansible modern, mekanisme dynamic inventory diimplementasikan lewat inventory plugins. Plugin adalah komponen yang mengetahui cara berkomunikasi dengan penyedia tertentu. Dua yang paling populer adalah amazon.aws.aws_ec2 (AWS EC2) dan google.gcp.gcp_compute (Google Cloud Compute Engine).
Konfigurasi plugin cukup didefinisikan dalam file YAML, lalu file itu dipakai sebagai argumen -i:
plugin: amazon.aws.aws_ec2
regions:
- ap-southeast-1
filters:
instance-state-name: running
tag:Environment: production
keyed_groups:
- key: tags.Name
prefix: tag
- key: tags.Role
prefix: role
compose:
ansible_host: public_ip_addressBeberapa poin penting dari konfigurasi di atas:
filters — menyaring instance yang masuk inventory, misalnya hanya yang running dan di environment production. Ini mencegah Ansible mencoba menghubungi instance yang mati.keyed_groups — mengelompokkan host otomatis berdasarkan metadata cloud (tags/labels). Instance dengan tag Role: web otomatis masuk grup role_web tanpa perlu menulis satu baris pun.compose — memetakan variabel dari data cloud. Contohnya ansible_host diambil dari public IP instance.Important
Plugin seperti aws_ec2 dan gcp_compute bukan bagian dari ansible-core, melainkan dari Collections (amazon.aws dan google.gcp). Kalian perlu menginstallnya terlebih dahulu, misalnya lewat ansible-galaxy collection install amazon.aws. Detail tentang Collections akan kita bahas tuntas di episode 13.
Untuk kebutuhan kredensial, plugin membaca dari variable environment standar cloud (misalnya AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) atau file service account. Sama seperti host variables, jangan pernah menyimpan kredensial di dalam file konfigurasi plugin yang masuk Git.
Mari kita tutup dengan daftar kesalahan yang paling sering membuat praktisi terjebak:
| Kesalahan | Gejala | Solusi |
|---|---|---|
| Indentasi YAML tidak konsisten | Error mapping values are not allowed here saat parsing | Perhatikan indentasi; lebih baik pasang ekstensi Red Hat YAML di editor |
| Mengira key inventory = IP yang bisa dihubungi | Error Failed to connect to the host via ssh | Definisikan IP asli lewat ansible_host |
Pattern berisi : tanpa tanda kutip | Shell menafsirkan karakter spesial, target host salah | Selalu kutip pattern: ansible 'webservers:&staging' |
| Grup di-referensikan tapi tidak pernah didefinisikan | Error the host group 'xxx' does not exist | Jalankan ansible-inventory --graph untuk verifikasi struktur |
| Kredensial SSH ditulis hardcode | Kebocoran rahasia di repository | Pakai SSH key + Vault |
Pada episode 3 ini, kita telah membahas inventory secara menyeluruh: format INI vs YAML, hierarki host groups, host variables untuk mengatur koneksi SSH, host patterns untuk menargetkan server secara presisi, verifikasi dengan ansible-inventory, hingga pengenalan dynamic inventory untuk infrastruktur cloud yang bergerak dinamis.
Inti dari episode ini sederhana namun sangat menentukan: inventory adalah peta infrastruktur kalian, dan seluruh skill automasi selanjutnya — ad-hoc command, playbook, handler, hingga roles — selalu berjalan di atas inventory.
Di episode 4 selanjutnya, kita akan menggunakan inventory ini untuk praktik nyata: Ad-Hoc Commands untuk keperluan operasional harian, seperti cek status server, mengelola file, install package, hingga restart layanan — semuanya dari satu command line. Pastikan tetap semangat!