Ansible mengelola konfigurasi di setiap server yang saya jalankan di Commsult Indonesia — delapan DigitalOcean Droplet dan tiga instance GCP Compute Engine. Tanpa Ansible, setiap server adalah snowflake: konfigurasi Nginx yang sedikit berbeda, versi Node.js yang berbeda, aturan firewall yang diterapkan secara manual dalam urutan yang berbeda. Ansible menjadikan server seperti ternak, bukan peliharaan — server mana pun dapat di-reprovisioning dari awal dalam waktu kurang dari sepuluh menit dan akan identik dengan setiap server lain dalam grup role-nya. Panduan ini mencakup pola yang benar-benar berfungsi di produksi, bukan contoh tutorial yang rusak dalam kondisi nyata.
Role Ansible adalah unit fundamental otomasi modular. Sebuah role mengelola satu tanggung jawab: menginstal Nginx, mengonfigurasi PostgreSQL, menyiapkan aplikasi Node.js, atau mengonfigurasi firewall. Jangan menulis satu playbook monolitik yang melakukan segalanya — Anda tidak akan pernah bisa menguji atau menggunakannya kembali. Struktur direktori role standar mencakup tasks/main.yml (daftar task), handlers/main.yml (tindakan restart/reload yang dipicu oleh perubahan task), templates/ (template file konfigurasi Jinja2), vars/ (variabel spesifik role), dan defaults/ (default yang dapat ditimpa). Pemisahan antara vars/ dan defaults/ penting: vars/ tidak dapat ditimpa oleh pemanggil, defaults/ bisa.
Setiap task Ansible harus idempoten — menjalankan playbook dua kali pada host yang sama harus menghasilkan hasil yang sama seperti menjalankannya sekali. Ini berarti menggunakan modul yang tepat untuk setiap tindakan: gunakan apt atau yum daripada shell: apt-get install; gunakan copy atau template daripada shell: echo; gunakan systemd daripada shell: service restart. Ketika Anda harus menggunakan modul shell atau command (terkadang tidak dapat dihindari untuk konfigurasi kompleks), gunakan parameter creates: atau removes: untuk membuat task melewati eksekusi jika efeknya sudah ada. Idempotency memungkinkan Anda menjalankan ulang playbook dengan aman untuk memaksa drift konfigurasi kembali ke baseline.
File inventory datar tidak dapat diskalakan lebih dari beberapa server. Gunakan direktori inventory dengan file terpisah per environment atau per grup role. Inventory dinamis bahkan lebih baik untuk infrastruktur cloud: plugin gcp_compute secara otomatis menemukan instance Compute Engine berdasarkan label, dan plugin digitalocean menemukan Droplet berdasarkan tag. Dengan inventory dinamis, menambahkan server baru ke grup tag secara otomatis menyertakannya dalam jalannya playbook berikutnya — tidak perlu pengeditan inventory manual. Di GCP, saya menggunakan label instance seperti role=web-server dan env=production untuk secara otomatis mengelompokkan instance untuk penargetan playbook.
Dari pengalaman saya: selalu jalankan playbook dengan --check --diff sebelum menerapkannya ke produksi. Mode check menampilkan setiap perubahan yang akan dilakukan tanpa melakukannya; --diff menampilkan perbedaan konten file yang tepat. Saya menambahkan langkah CI yang menjalankan ansible-playbook --check --diff --limit staging terhadap inventory staging kami pada setiap pull request. Jika check staging lulus, saya menerapkan secara manual ke prod. Ini menangkap tiga kesalahan konfigurasi yang akan merusak Nginx produksi dalam setahun terakhir.
Jangan pernah menyimpan secrets dalam plaintext di repository Ansible Anda. Password database, API key, konten sertifikat SSL, dan kredensial apa pun yang memberikan akses ke sistem harus dienkripsi. Ansible Vault mengenkripsi variabel individual atau seluruh file menggunakan AES-256. Password vault dapat disimpan dalam file (dikecualikan dari Git melalui .gitignore), dilewatkan melalui --vault-password-file, atau diambil dari secrets manager seperti HashiCorp Vault atau GCP Secret Manager melalui skrip password vault. Di produksi, saya menggunakan skrip Python sebagai penyedia password vault yang mengambil kunci dekripsi dari GCP Secret Manager saat runtime playbook — tidak ada file password vault di disk di mana pun.
# Encrypt a secret with Ansible Vault
ansible-vault encrypt_string 'db_password_here' --name 'db_password'
# Output stored in group_vars/prod/vault.yml:
# db_password: !vault |
# $ANSIBLE_VAULT;1.1;AES256
# ...
# Run playbook with vault password from GCP Secret Manager
ansible-playbook site.yml --vault-password-file=scripts/vault-password-from-gcp.py --inventory=inventories/production --limit=web-servers --check --diff
# Production deployment with rolling update
ansible-playbook deploy.yml --inventory=inventories/production --serial 1 --tags=deployHandler di Ansible berjalan di akhir play, bukan segera ketika diberitahu. Ini mencegah kesalahan umum me-restart Nginx beberapa kali selama satu jalannya ketika tiga task berbeda semuanya memodifikasi konfigurasi Nginx. Ketiga task tersebut memberi tahu handler 'reload nginx' yang sama, yang berjalan sekali setelah semua task selesai. Gunakan reload daripada restart untuk Nginx dan layanan serupa — reload membaca konfigurasi baru tanpa menjatuhkan koneksi yang ada. Gunakan restart hanya untuk layanan yang tidak mendukung reload graceful (beberapa daemon memerlukan restart penuh untuk mengambil perubahan konfigurasi).
┌─────────────────────────────────────────────────┐
│ Ansible Role Directory Structure │
├─────────────────────────────────────────────────┤
│ roles/nginx/ │
│ ├── tasks/ │
│ │ └── main.yml (task list) │
│ ├── handlers/ │
│ │ └── main.yml (reload/restart actions) │
│ ├── templates/ │
│ │ └── nginx.conf.j2 (Jinja2 config) │
│ ├── vars/ │
│ │ └── main.yml (non-overridable vars) │
│ └── defaults/ │
│ └── main.yml (overridable defaults) │
└─────────────────────────────────────────────────┘Molecule adalah framework pengujian standar untuk role Ansible. Ia menyediakan container atau VM, menjalankan role Anda, dan memverifikasi hasilnya menggunakan Testinfra (assertion berbasis Python pada state sistem). Tes Molecule untuk role Nginx memeriksa bahwa layanan nginx berjalan, bahwa port 80 dan 443 mendengarkan, bahwa file konfigurasi berisi direktif yang diharapkan, dan bahwa konfigurasi Nginx lulus validasi nginx -t. Menjalankan tes Molecule di CI (pada setiap perubahan role) menangkap regresi sebelum mencapai produksi. Molecule berjalan di Docker secara default, membuatnya cepat dan gratis untuk pipeline CI.
Saya menjalankan playbook Ansible awal kami sebagai root melalui become: yes di level play, yang berarti setiap task berjalan dengan hak istimewa sistem penuh. Ini berbahaya — bug dalam task template dapat menimpa /etc/passwd dengan sampah. Pendekatan yang benar: jalankan sebagai akun layanan terbatas (ansible-runner) dengan akses sudo dibatasi pada perintah tertentu melalui sudoers. Gunakan become: yes hanya di level task ketika eskalasi benar-benar diperlukan. Eskalasi hak istimewa harus menjadi pengecualian, bukan default. Selain itu, kunci node kontrol Ansible — hanya node itu yang harus memiliki akses SSH ke node yang dikelola di port 22.
Untuk deployment aplikasi zero-downtime menggunakan Ansible, gunakan kata kunci serial untuk menerapkan perubahan ke satu server sekaligus secara rolling. Dengan serial: 1, Ansible men-deploy ke web server pertama, menunggu health check lulus, lalu berpindah ke yang kedua. Jika health check gagal, play berhenti dan server yang tersisa tidak tersentuh — membatasi blast radius. Gabungkan dengan task delegate_to: localhost yang memperbarui pool backend load balancer untuk sementara menguras target server sebelum deployment dan menambahkannya kembali setelahnya.
Saya menggunakan keduanya di Commsult Indonesia, tetapi untuk hal yang berbeda. Terraform menyediakan infrastruktur — membuat server, jaringan, database. Ansible mengonfigurasi apa yang sudah disediakan — menginstal paket, menulis file konfigurasi, mengelola layanan. Tumpang tindihnya minimal: Ansible dapat menyediakan resource cloud (melalui modul untuk GCP dan DigitalOcean), dan Terraform dapat menjalankan provisioner. Tetapi menggunakan setiap alat untuk tujuan utamanya memberikan modularitas yang lebih baik dan pemisahan concern yang lebih bersih. Satu catatan penting untuk tim Indonesia: arsitektur agentless Ansible adalah keunggulan besar dibandingkan alternatif seperti Puppet atau Chef — tidak ada yang perlu diinstal pada node yang dikelola selain Python dan SSH, yang ada di setiap server Linux secara default.
Sumber & Bacaan Lanjutan