Apa itu Inventory? #
Dalam setiap inisiatif otomatisasi infrastruktur, kejelasan mengenai target eksekusi adalah hal yang paling krusial. Sebelum kita dapat menginstal paket aplikasi, memperbarui konfigurasi sistem, atau memicu proses deployment, kita harus menjawab satu pertanyaan mendasar: Ke server mana instruksi ini harus dikirimkan? Di dalam ekosistem Ansible, jawaban dari pertanyaan tersebut dikelola secara terpusat oleh komponen bernama Inventory (Inventaris). Artikel ini membahas konsep dasar inventaris sebagai sumber kebenaran tunggal (single source of truth) infrastruktur kita, membandingkan format berkas yang didukung, membedah struktur grup bawaan dan pola pengelompokan hierarkis, hingga cara Ansible membaca dan memvalidasi inventaris tersebut.
Sumber Kebenaran Infrastruktur #
Di Ansible, inventaris bukan sekadar daftar alamat IP statis yang diketik di dalam sebuah file. Inventaris adalah abstraksi deklaratif dari seluruh mesin, server virtual, perangkat jaringan, atau container yang dikelola. Ia bertindak sebagai Sumber Kebenaran (Source of Truth) yang memisahkan logika tindakan otomatisasi (apa yang dilakukan di playbook) dengan data target (siapa yang menerima tindakan tersebut).
Secara sistematis, berkas inventaris mendefinisikan empat dimensi utama dari infrastruktur kita:
- Identitas Node (Who): Nama host (hostname), nama domain (FQDN), atau alamat IP dari setiap target managed node.
- Pengelompokan Logis (How to group): Klasifikasi server berdasarkan fungsi (misalnya grup
webservers,dbservers), berdasarkan lingkungan (development,production), atau berdasarkan wilayah geografis (jakarta,surabaya). - Kontekstualisasi Variabel (What variables): Data konfigurasi spesifik yang diikat pada grup server tertentu atau host tertentu (misalnya port HTTP, jalur direktori log, atau nama database).
- Metode Penghubung (How to connect): Parameter taktis yang digunakan Ansible untuk menginisiasi koneksi SSH, seperti user login (
ansible_user), port SSH kustom (ansible_port), dan lokasi file kunci privat (ansible_ssh_private_key_file).
Ketika kita menjalankan playbook, Ansible akan memproses berkas inventaris terlebih dahulu untuk memetakan server mana saja yang masuk ke dalam cakupan eksekusi, merakit data variabel yang berlaku untuk masing-masing host, baru kemudian menginisiasi koneksi paralel untuk menjalankan modul otomatisasi.
Format INI dan YAML #
Ansible mendukung dua format penulisan berkas inventaris statis: INI dan YAML. Kedua format ini akan menghasilkan struktur data internal yang sama persis di memori Ansible. Pilihan format sepenuhnya bergantung pada kompleksitas infrastruktur dan kenyamanan tim pengembang kita.
1. Format INI (Standard Tradisional) #
Format INI adalah format bawaan asli Ansible yang paling populer karena strukturnya yang sangat ringkas, sederhana, dan mudah dibaca secara cepat. Format ini sangat cocok untuk inventaris skala kecil hingga menengah yang ditulis dan dipelihara secara manual oleh administrator sistem.
Berikut contoh berkas inventaris format INI:
# File: inventory/production/hosts.ini
# Server tanpa grup (otomatis masuk grup 'ungrouped')
bastion.unisbadri.com
# Pengelompokan server berdasarkan fungsi
[webservers]
web-01.unisbadri.com http_port=80
web-02.unisbadri.com http_port=8080
192.168.56.12 http_port=80
[dbservers]
db-primary.unisbadri.com
db-replica-01.unisbadri.com
# Grup yang menggabungkan grup lain (Hierarki)
[datacenter:children]
webservers
dbservers
# Pendefinisian variabel yang berlaku untuk seluruh host di grup tertentu
[webservers:vars]
ansible_user=ubuntu
nginx_version=1.24
2. Format YAML (Standard Modern) #
Format YAML bersifat lebih eksplisit, memiliki struktur berbasis indentasi yang ketat, dan sangat cocok digunakan jika kita sering menghasilkan file inventaris secara otomatis (programmatically) menggunakan skrip eksternal atau sistem integrasi CI/CD. Keunggulan format ini adalah konsistensi sintaksis dengan file playbook Ansible yang juga ditulis dalam format YAML.
Berikut contoh berkas inventaris yang sama namun ditulis dalam format YAML:
# File: inventory/production/hosts.yml
---
all:
hosts:
bastion.unisbadri.com: {}
children:
webservers:
hosts:
web-01.unisbadri.com:
http_port: 80
web-02.unisbadri.com:
http_port: 8080
192.168.56.12:
http_port: 80
vars:
ansible_user: ubuntu
nginx_version: "1.24"
dbservers:
hosts:
db-primary.unisbadri.com: {}
db-replica-01.unisbadri.com: {}
datacenter:
children:
webservers: {}
dbservers: {}
3. Penulisan Jangkauan Host (Host Ranges) #
Ketika kita harus mendefinisikan puluhan hingga ratusan server yang memiliki pola nama berurutan (misalnya web-01.example.com hingga web-50.example.com), kita tidak perlu menulisnya satu per satu. Ansible mendukung sintaksis jangkauan numerik (numerical ranges) dan jangkauan alfabet (alphabetic ranges).
- Jangkauan Numerik (Format INI):
[webservers] # Mendefinisikan web-01.example.com sampai web-50.example.com web-[01:50].example.com # Mendefinisikan IP 192.168.1.10 sampai 192.168.1.25 192.168.1.[10:25] - Jangkauan Numerik (Format YAML):
webservers: hosts: # Penulisan range numerik di YAML tetap dibungkus tanda kutip "web-[01:50].example.com": {} "192.168.1.[10:25]": {} - Jangkauan Alfabet (Format INI):
[dbservers] # Mendefinisikan db-a.example.com sampai db-f.example.com db-[a:f].example.com
Fitur jangkauan ini memangkas ukuran berkas inventaris secara drastis serta mengurangi resiko kesalahan ketik saat menambahkan deretan server baru yang homogen.
Struktur Grup Bawaan dan Hierarki #
Setiap kali kita memuat inventaris, Ansible secara otomatis membuat dua grup implisit yang tidak perlu kita deklarasikan secara tertulis di dalam file:
all: Grup akar yang mencakup setiap host yang didefinisikan di dalam seluruh inventaris tanpa terkecuali.ungrouped: Grup penampung untuk setiap host yang didefinisikan di luar blok grup mana pun (seperti hostbastion.unisbadri.compada contoh di atas).
Visualisasi struktur pohon grup bawaan dan kustom ini digambarkan pada diagram di bawah:
flowchart TD
A["Grup all (Bawaan)"] --> B["Grup ungrouped (Bawaan)"]
A --> C["Grup datacenter (Kustom)"]
B --> D["bastion.unisbadri.com"]
C --> E["Grup webservers (Anak)"]
C --> F["Grup dbservers (Anak)"]
E --> G["web-01.unisbadri.com"]
E --> H["web-02.unisbadri.com"]
E --> I["192.168.56.12"]
F --> J["db-primary.unisbadri.com"]
F --> K["db-replica-01.unisbadri.com"]
Pewarisan Grup dan Variabel Bersama #
Membangun struktur grup hierarkis menggunakan parameter :children (INI) atau children: (YAML) memungkinkan kita menyusun relasi pewarisan properti yang elegan. Sebagai contoh, grup induk datacenter di atas menggabungkan grup webservers dan dbservers.
Jika kita mendefinisikan variabel di level grup datacenter, seluruh server yang berada di bawah grup anak (webservers dan dbservers) secara otomatis akan mewarisi variabel tersebut:
[datacenter:children]
webservers
dbservers
[datacenter:vars]
# Variabel ini diwarisi oleh web-01, web-02, db-primary, dan db-replica
ntp_server=time.unisbadri.com
dns_resolver=1.1.1.1
Fleksibilitas Targeting Menggunakan Patterns dan Limits #
Dengan struktur pengelompokan di atas, kita dapat mengarahkan eksekusi playbook secara sangat fleksibel menggunakan parameter hosts: pada playbook atau menggunakan flag limit (--limit) di baris perintah CLI.
Tabel di bawah ini menjelaskan pola pencocokan (patterns) yang dapat kita gunakan untuk menyaring server target:
| Sintaks Pattern | Target Penerima | Penjelasan Logika |
|---|---|---|
all |
Semua host | Menjalankan tugas di seluruh server di inventaris. |
webservers |
Hanya grup webservers |
Menjalankan tugas di semua host dalam grup tersebut. |
webservers[0] |
Server pertama grup | Mengambil index pertama (dalam contoh ini web-01). |
webservers[1:3] |
Range index server | Mengambil server index ke-1 sampai ke-3 di dalam grup. |
webservers:dbservers |
Penggabungan (Union) | Semua server yang berada di grup webservers ATAU dbservers. |
webservers:&dbservers |
Irisan (Intersection) | Hanya server yang masuk di grup webservers DAN dbservers. |
webservers:!dbservers |
Pengecualian (Exclusion) | Server di grup webservers TETAPI BUKAN anggota dbservers. |
web*:db* |
Karakter wildcard * |
Semua grup yang diawali dengan kata web atau db. |
Contoh penggunaan operasional di terminal:
# Hanya jalankan playbook pada server database replica
ansible-playbook -i inventory/hosts.ini playbooks/upgrade.yml --limit "dbservers_replica"
# Jalankan playbook di semua webserver KECUALI yang berada di CDN
ansible-playbook -i inventory/hosts.ini playbooks/deploy.yml --limit "webservers:!webservers_cdn"
# Jalankan ping ad-hoc hanya ke irisan server web yang berada di wilayah Jakarta
ansible -i inventory/hosts.ini "webservers:&jakarta" -m ping
Direktori Inventaris Bersama #
Ketika mengelola infrastruktur tingkat perusahaan (enterprise), satu berkas inventaris tunggal sering kali menjadi terlalu besar dan sulit dikelola karena berbagai tim memiliki tanggung jawab server yang berbeda (misalnya tim keamanan mengelola server monitoring, tim database mengelola cluster database).
Untuk mengatasi hal ini, kita dapat mengonfigurasi parameter inventory pada file ansible.cfg untuk mengarah ke sebuah direktori, bukan ke sebuah file tunggal.
# File: ansible.cfg
[defaults]
inventory = inventory/production/
Di dalam direktori inventory/production/ tersebut, kita dapat memecah inventaris menjadi beberapa file berdasarkan kepemilikan atau jenis server:
inventory/production/
├── 01-infrastructure.ini # Berkas bastion dan core network
├── 02-web-tier.yml # Inventaris server aplikasi web
├── 03-database-tier.ini # Inventaris database cluster
└── group_vars/ # Variabel grup terpadu
├── all.yml
└── webservers.yml
Aturan Penggabungan Direktori oleh Ansible: #
- Urutan Abjad: Ansible akan membaca seluruh file di dalam direktori tersebut berdasarkan urutan abjad namanya.
- Abaikan Ekstensi Cadangan: Berkas yang diakhiri dengan ekstensi cadangan umum (seperti
~,.bak,.orig,.retry, atau.old) akan diabaikan secara otomatis oleh Ansible untuk mencegah pemuatan server duplikat atau usang. - Penggabungan Grup: Jika nama grup yang sama didefinisikan di dalam file
02-web-tier.ymldan03-database-tier.ini, Ansible secara cerdas akan menggabungkan daftar host dari kedua file tersebut ke dalam satu grup memori terpadu.
Algoritma Cara Kerja Pembacaan #
Untuk mempermudah pemecahan masalah (debugging) ketika ada variabel yang memiliki nilai yang tidak sesuai ekspektasi kita, penting bagi kita untuk memahami bagaimana urutan algoritma Ansible saat membaca dan merakit seluruh berkas inventaris dari piringan keras (disk) ke dalam memori runtime.
Ansible mengeksekusi langkah-langkah pemuatan dengan urutan berikut:
flowchart TD
Step1["1. Cari berkas inventaris di jalur yang ditentukan (argumen -i atau ansible.cfg)"]
Step2["2. Parsing berkas fisik (INI/YAML) untuk membangun relasi host dan grup"]
Step3["3. Parsing subdirektori group_vars/ yang sejajar dengan file inventaris:<br/>- Baca group_vars/all.yml (Muat variabel global)<br/>- Baca group_vars/<nama_grup>.yml (Muat variabel grup spesifik)"]
Step4["4. Parsing subdirektori host_vars/ yang sejajar dengan file inventaris:<br/>- Baca host_vars/<nama_host>.yml (Muat variabel spesifik host)"]
Step5["5. Lakukan resolusi pewarisan variabel (Precedence resolving):<br/>- Variabel host_vars menimpa group_vars, group_vars menimpa group_vars/all"]
Step6["6. Rakit struktur data hostvars akhir untuk dieksekusi oleh Engine Playbook"]
Step1 --> Step2
Step2 --> Step3
Step3 --> Step4
Step4 --> Step5
Step5 --> Step6
Mekanisme ini memastikan bahwa data variabel yang paling spesifik (seperti variabel tingkat host) akan selalu memiliki prioritas lebih tinggi untuk digunakan daripada data variabel yang bersifat umum (seperti variabel tingkat grup).
Memeriksa dan Menelusuri Inventaris #
Jangan pernah menjalankan playbook secara langsung jika kita tidak yakin apakah Ansible telah membaca konfigurasi grup dan server kita dengan benar. Ansible menyediakan alat penelusuran bawaan khusus bernama ansible-inventory.
Berikut adalah perintah-perintah diagnostik penting yang wajib kita kuasai:
1. Menampilkan Grafik Hubungan Host dan Grup #
Perintah ini memberikan gambaran visual berbentuk pohon yang sangat mudah dibaca tentang bagaimana struktur grup dan anak grup kita saling terhubung:
ansible-inventory -i inventory/production/ --graph
Output yang dihasilkan akan memetakan relasi hierarkis:
@all:
|--@datacenter:
| |--@webservers:
| | |--web-01.unisbadri.com
| | |--web-02.unisbadri.com
| | |--192.168.56.12
| |--@dbservers:
| | |--db-primary.unisbadri.com
| | |--db-replica-01.unisbadri.com
|--@ungrouped:
| |--bastion.unisbadri.com
2. Menampilkan Seluruh Data Inventaris format JSON #
Perintah ini berguna saat kita ingin melihat seluruh variabel yang melekat pada setiap host setelah proses resolusi precedence selesai dilakukan oleh Ansible:
ansible-inventory -i inventory/production/ --list
3. Memeriksa Variabel untuk Satu Host Tertentu #
Jika kita ingin fokus melacak variabel apa saja yang aktif pada satu server target tanpa terganggu oleh server lainnya, gunakan flag --host:
ansible-inventory -i inventory/production/ --host web-01.unisbadri.com
Outputnya akan menyajikan seluruh variabel koneksi dan variabel kustom dalam format JSON bersih:
{
"ansible_user": "ubuntu",
"http_port": 80,
"nginx_version": "1.24",
"ansible_host": "web-01.unisbadri.com"
}
Ringkasan #
- Peta Otomatisasi — Inventaris adalah representasi deklaratif dari infrastruktur target yang bertindak sebagai sumber kebenaran tunggal untuk memisahkan data dengan logika playbook.
- Dua Format Utama — Format INI direkomendasikan untuk proyek sederhana karena kemudahan penulisan manual; format YAML digunakan untuk integrasi sistem otomatis.
- Dukungan Jangkauan — Memanfaatkan sintaksis range numerik
[01:50]atau alfabet[a:f]memperkecil ukuran berkas dan meminimalkan typo saat mendaftarkan server homogen.- Grup Bawaan all & ungrouped — Ansible menyusun semua host di bawah grup akar
all, dan memasukkan host tanpa grup ke dalam grup implisitungrouped.- Fleksibilitas limit — Kita dapat menggunakan filter pattern matching di CLI (seperti exclusion
!atau intersection&) untuk membatasi ruang lingkup eksekusi playbook secara aman.- Penggunaan Direktori — Mengarahkan parameter inventaris ke sebuah folder memungkinkan pemecahan berkas hosts berdasarkan kemitraan tim tanpa resiko tumpang tindih.
- Diagnostik Efektif — Perintah
ansible-inventory --graphwajib dijalankan sebelum eksekusi playbook guna memastikan struktur hubungan server terbaca dengan sempurna.