Handler #
Ada kategori aksi dalam pengelolaan server yang hanya perlu dilakukan saat ada perubahan nyata — reload nginx setelah konfigurasi diubah, restart aplikasi setelah kode di-deploy, atau reload systemd setelah unit file ditambahkan. Jika kamu memasukkan aksi-aksi ini sebagai task biasa, mereka akan selalu dijalankan tanpa peduli apakah ada yang berubah atau tidak. Di sinilah handler hadir: task khusus yang hanya berjalan saat dipicu oleh task lain, dan hanya jika task pemicunya benar-benar menghasilkan perubahan.
Handler vs Task Biasa #
Perbedaan fundamental antara handler dan task biasa ada di kapan mereka dijalankan:
# Task biasa: SELALU dijalankan saat playbook berjalan
tasks:
- name: Deploy konfigurasi nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
- name: Reload nginx ← SELALU reload, bahkan jika konfigurasi tidak berubah
systemd:
name: nginx
state: reloaded
# Handler: hanya dijalankan jika task notify-nya menghasilkan "changed"
tasks:
- name: Deploy konfigurasi nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Reload nginx ← trigger handler hanya jika file BERUBAH
handlers:
- name: Reload nginx ← hanya dijalankan jika di-notify
systemd:
name: nginx
state: reloaded
Dengan handler, nginx hanya di-reload saat konfigurasi benar-benar berubah. Jika konfigurasi tidak berubah (file sudah identik), tidak ada yang terjadi. Ini lebih efisien dan lebih aman.
Kapan Handler Dijalankan #
Handler tidak langsung dieksekusi saat di-notify. Mereka dikumpulkan dan dieksekusi setelah semua task dalam play selesai:
Task 1: Deploy nginx.conf → changed → notify "Reload nginx"
Task 2: Deploy SSL cert → changed → notify "Reload nginx"
Task 3: Deploy app config → ok (tidak berubah)
Task 4: Update robots.txt → changed → notify "Reload nginx"
--- Semua task selesai ---
Handler: Reload nginx → dieksekusi SEKALI
(meski di-notify 3 kali, hanya berjalan satu kali)
Perilaku ini sangat efisien — tidak peduli berapa banyak task yang mengubah konfigurasi nginx, reload hanya terjadi satu kali di akhir.
Karena handler dijalankan di akhir play, jika playbook berhenti di tengah jalan karena ada task yang gagal, handler yang sudah di-notify tidak akan dijalankan. Gunakan --force-handlers saat menjalankan playbook jika kamu ingin handler tetap berjalan meski ada kegagalan.Mendefinisikan dan Memanggil Handler #
Handler didefinisikan di bagian handlers: play, dan dipanggil dari task menggunakan notify::
tasks:
- name: Deploy konfigurasi nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify:
- Reload nginx
- Update log rotation # Bisa notify beberapa handler sekaligus
- name: Tambahkan virtual host baru
template:
src: vhost.conf.j2
dest: /etc/nginx/sites-available/myapp.conf
notify: Reload nginx # Notify handler yang sama
handlers:
- name: Reload nginx
systemd:
name: nginx
state: reloaded
- name: Update log rotation
command: logrotate -f /etc/logrotate.d/nginx
Nama handler adalah identifier — pastikan nama di notify: sama persis (case-sensitive) dengan nama di handlers:.
Handler Berantai (listen) #
Ansible mendukung pola di mana beberapa handler “mendengarkan” satu event yang sama menggunakan listen:
handlers:
- name: Restart stack aplikasi # nama handler
systemd:
name: myapp
state: restarted
listen: "restart app stack" # event yang didengarkan
- name: Clear application cache
command: redis-cli flushdb
listen: "restart app stack" # handler ini juga mendengarkan event yang sama
- name: Notify monitoring
uri:
url: "https://monitoring.example.com/api/deployments"
method: POST
listen: "restart app stack"
# Di task, cukup notify event-nya:
tasks:
- name: Deploy kode baru
git:
repo: https://github.com/org/app.git
dest: /opt/app
notify: "restart app stack" # Trigger SEMUA handler yang listen event ini
Pola ini memisahkan concern dengan bersih — task tidak perlu tahu ada berapa handler yang akan bereaksi, cukup notify event yang relevan.
Memaksa Handler Berjalan Segera #
Secara default, handler berjalan di akhir play. Tapi ada kasus di mana kamu butuh handler berjalan lebih awal — misalnya saat ada task berikutnya yang bergantung pada hasil handler:
tasks:
- name: Deploy konfigurasi database baru
template:
src: postgresql.conf.j2
dest: /etc/postgresql/15/main/postgresql.conf
notify: Restart PostgreSQL
# Jalankan semua handler yang sudah di-notify sejauh ini
- name: Flush handlers sekarang
meta: flush_handlers
# Task ini butuh PostgreSQL sudah restart dengan konfigurasi baru
- name: Jalankan migrasi database
command: python manage.py migrate
meta: flush_handlers memaksa semua handler yang sudah di-notify untuk dieksekusi saat itu juga, bukan menunggu akhir play.
Handler di dalam Role #
Saat menggunakan role, handler didefinisikan di roles/<rolename>/handlers/main.yml dan otomatis tersedia untuk semua task dalam role tersebut:
roles/nginx/
├── tasks/
│ └── main.yml # Task yang notify handler
└── handlers/
└── main.yml # Definisi handler untuk role nginx
# roles/nginx/handlers/main.yml
---
- name: Reload nginx
systemd:
name: nginx
state: reloaded
- name: Restart nginx
systemd:
name: nginx
state: restarted
Handler yang didefinisikan dalam role hanya tersedia untuk task dalam role yang sama. Tapi jika kamu menggunakan listen, handler dari satu role bisa merespons notify dari role lain.
Ringkasan #
- Handler adalah task khusus yang hanya dieksekusi saat di-notify oleh task lain, dan hanya jika task pemicunya menghasilkan perubahan (
changed).- Handler dieksekusi di akhir play, bukan langsung saat di-notify — dan hanya sekali meski di-notify berkali-kali.
- Gunakan
notify:di task untuk memicu handler, dan definisikan handler di bagianhandlers:play atau dihandlers/main.ymlrole.listenmemungkinkan beberapa handler merespons satu event — berguna untuk memisahkan aksi-aksi yang terkait.meta: flush_handlersuntuk memaksa handler berjalan segera, bukan menunggu akhir play — gunakan saat task berikutnya bergantung pada hasil handler.- Handler tidak berjalan jika playbook berhenti karena error — gunakan
--force-handlersjika diperlukan.
← Sebelumnya: Task & Module Execution Berikutnya: Notify & Listen →