Anti-Pattern #
Inventory yang buruk adalah sumber masalah yang tidak langsung terlihat — playbook berjalan, tapi hasil akhirnya tidak konsisten, ada variabel yang tiba-tiba salah nilainya, atau deployment ke production terjadi padahal yang dimaksud staging. Masalah-masalah ini jarang muncul saat pertama kali membuat inventory, tapi menumpuk seiring berjalannya waktu. Artikel ini membahas anti-pattern yang paling sering ditemukan dan bagaimana cara menghindarinya.
Anti-Pattern 1: Grup Berdasarkan Lokasi, Bukan Fungsi #
Mengelompokkan server berdasarkan lokasi fisik atau nama datacenter terasa intuitif, tapi menciptakan masalah saat infrastruktur berkembang.
# ANTI-PATTERN: grup berdasarkan lokasi
[datacenter_jakarta]
web-01
db-01
cache-01
[datacenter_surabaya]
web-02
db-02
Masalahnya: saat kamu ingin menjalankan playbook “deploy aplikasi ke semua web server”, tidak ada cara mudah untuk menargetkan hanya web server dari semua datacenter. Kamu harus menyebutkan host satu per satu atau membuat grup baru yang redundan.
# BENAR: grup berdasarkan fungsi, gunakan variabel untuk lokasi
[webservers]
web-01 datacenter=jakarta
web-02 datacenter=surabaya
[dbservers]
db-01 datacenter=jakarta
db-02 datacenter=surabaya
[cacheservers]
cache-01 datacenter=jakarta
Dengan pendekatan ini, kamu bisa menargetkan fungsi (webservers) atau membuat grup turunan berdasarkan lokasi jika memang diperlukan untuk kasus tertentu.
Anti-Pattern 2: Variabel Sensitif dalam Plaintext #
Menyimpan password, API key, atau token langsung di file inventory adalah risiko keamanan serius — terutama jika inventory disimpan di repository Git.
# ANTI-PATTERN: password dalam plaintext di inventory
[dbservers:vars]
db_password=SuperSecret123
aws_access_key=AKIAIOSFODNN7EXAMPLE
aws_secret_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# ANTI-PATTERN: password dalam plaintext di group_vars
# group_vars/dbservers.yml
db_password: SuperSecret123
Satu kali file ini masuk ke Git history, password tersebut akan tersimpan selamanya — bahkan setelah dihapus di commit berikutnya.
# BENAR: gunakan Ansible Vault untuk nilai sensitif
# group_vars/dbservers.yml
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
61363636666134316233626133386566623834613836396166323666...
# Atau simpan variabel sensitif di file terpisah yang dienkripsi:
# group_vars/dbservers/vars.yml → variabel tidak sensitif
# group_vars/dbservers/vault.yml → variabel sensitif, dienkripsi dengan Vault
Anti-Pattern 3: Satu Inventory untuk Semua Lingkungan #
Menggabungkan semua lingkungan dalam satu file inventory dengan nama grup yang dibedakan adalah pola yang sangat umum dan sangat berbahaya.
# ANTI-PATTERN: semua lingkungan dalam satu inventory
[webservers_production]
prod-web-01
prod-web-02
[webservers_staging]
staging-web-01
[dbservers_production]
prod-db-01
[dbservers_staging]
staging-db-01
Masalahnya: tidak ada yang mencegah kamu menjalankan playbook dengan --limit webservers_production saat bermaksud ke staging. Satu typo bisa menyebabkan perubahan tidak sengaja ke production.
# BENAR: inventory terpisah per lingkungan
environments/
├── production/
│ ├── hosts.ini # Hanya host production
│ └── group_vars/
│ └── all.yml # Variabel production
└── staging/
├── hosts.ini # Hanya host staging
└── group_vars/
└── all.yml # Variabel staging
# Deployment harus eksplisit memilih lingkungan
ansible-playbook -i environments/staging/ deploy.yml # Staging
ansible-playbook -i environments/production/ deploy.yml # Production
Anti-Pattern 4: Terlalu Banyak Variabel di File Inventory #
Mendefinisikan puluhan variabel langsung di file hosts membuat inventory sulit dibaca dan di-maintain.
# ANTI-PATTERN: variabel bertumpuk di file inventory
[webservers:vars]
nginx_version=1.24
nginx_worker_processes=4
nginx_worker_connections=1024
nginx_keepalive_timeout=65
nginx_client_max_body_size=10m
http_port=80
https_port=443
ssl_certificate=/etc/ssl/certs/app.crt
ssl_certificate_key=/etc/ssl/private/app.key
app_port=8080
app_user=deployer
app_group=deployer
deploy_path=/opt/webapp
log_path=/var/log/webapp
# ... 30 variabel lagi
# BENAR: variabel di group_vars/ yang terorganisir
# group_vars/webservers/nginx.yml
nginx_version: "1.24"
nginx_worker_processes: 4
nginx_worker_connections: 1024
nginx_keepalive_timeout: 65
nginx_client_max_body_size: "10m"
# group_vars/webservers/ssl.yml
http_port: 80
https_port: 443
ssl_certificate: /etc/ssl/certs/app.crt
ssl_certificate_key: /etc/ssl/private/app.key
# group_vars/webservers/app.yml
app_port: 8080
app_user: deployer
deploy_path: /opt/webapp
File inventory (hosts.ini) seharusnya hanya berisi definisi host dan grup — bukan variabel.
Anti-Pattern 5: Nama Grup yang Tidak Konsisten #
Nama grup yang inkonsisten menciptakan kebingungan dan error yang sulit di-debug.
# ANTI-PATTERN: nama grup yang inkonsisten
[WebServers] # CamelCase
[db_server] # singular, underscore
[cache-servers] # plural, dash
[App] # terlalu singkat, ambigu
# BENAR: nama grup yang konsisten — lowercase, plural, underscore
[webservers]
[dbservers]
[cacheservers]
[appservers]
# Untuk sub-grup, gunakan pola yang konsisten:
[webservers_primary]
[webservers_replica]
Pilih satu konvensi dan terapkan secara konsisten di seluruh inventory. Nama grup digunakan di banyak tempat — di playbook, di group_vars/, di --limit argument — inkonsistensi di satu tempat akan menyebabkan error di tempat lain.
Anti-Pattern 6: Tidak Menggunakan group_vars/all untuk Variabel Global #
Mendefinisikan variabel yang sama di setiap file group_vars/ adalah bentuk duplikasi yang sulit di-maintain.
# ANTI-PATTERN: variabel sama didefinisikan di banyak file
# group_vars/webservers.yml
ansible_user: ubuntu
timezone: "Asia/Jakarta"
ntp_server: "0.id.pool.ntp.org"
# group_vars/dbservers.yml
ansible_user: ubuntu # duplikat!
timezone: "Asia/Jakarta" # duplikat!
ntp_server: "0.id.pool.ntp.org" # duplikat!
# BENAR: variabel global di group_vars/all.yml
# group_vars/all.yml
ansible_user: ubuntu
timezone: "Asia/Jakarta"
ntp_server: "0.id.pool.ntp.org"
# group_vars/webservers.yml — hanya variabel yang memang spesifik untuk webservers
nginx_version: "1.24"
http_port: 80
Ringkasan #
- Kelompokkan berdasarkan fungsi (webservers, dbservers), bukan lokasi — gunakan variabel untuk informasi lokasi.
- Jangan simpan secret dalam plaintext di inventory — gunakan Ansible Vault untuk semua nilai sensitif.
- Pisahkan inventory per lingkungan (production/, staging/) untuk mencegah kecelakaan deployment ke lingkungan yang salah.
- Variabel di group_vars/ (bukan di file inventory) — file inventory hanya untuk definisi host dan grup.
- Konsistensi nama grup: lowercase, plural, underscore — pilih satu konvensi dan terapkan di seluruh project.
- group_vars/all.yml untuk variabel yang benar-benar berlaku ke semua host — hindari duplikasi di setiap file group_vars.