Ansible: Cara Mengabaikan Host yang Tidak Terjangkau
Pelajari perbedaan failure dan unreachable di Ansible, serta cara memakai ignore_unreachable, serial, dan max_fail_percentage tanpa kehilangan host yang terlewat.
Host yang tidak dapat dijangkau bukan tugas yang gagal
Untuk mengabaikan host yang tidak dapat dijangkau di Ansible, tetapkan ignore_unreachable: true. Opsi ini berfungsi. Hal yang penting adalah mengetahui kapan opsi tersebut digunakan, karena Ansible menangani dua masalah yang berbeda dengan cara yang berbeda. Tugas yang berjalan pada host lalu mengembalikan error disebut failure. Host yang sama sekali tidak dapat dihubungi oleh Ansible disebut unreachable. ignore_errors hanya mencakup kasus pertama. ignore_unreachable hanya mencakup kasus kedua.
Berikut perbedaannya dalam ringkasan play.
PLAY RECAP *********************************************************************
web1 : ok=7 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0Ansible berhasil terhubung ke web1 dan menjalankan tujuh tugas. web2 menampilkan unreachable=1 dan failed=0, yang berarti tidak ada tugas yang berjalan pada host tersebut. Ansible tidak pernah berhasil membuat koneksi, sehingga menghapus host itu dari play dan melanjutkan proses pada host lainnya. Jika play tersebut memasang pembaruan keamanan, salah satu server Anda tidak akan mendapatkannya.
Apa yang menyebabkan host tidak dapat dijangkau
Tidak dapat dijangkau berarti koneksi gagal sebelum modul apa pun mencapai host. Tidak ada output modul yang dapat dibaca. Yang muncul hanya error koneksi, dan error tersebut muncul pada task pertama yang mengakses mesin.
fatal: [web2]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 203.0.113.20 port 22: Connection refused", "unreachable": true}Field msg memuat penyebab sebenarnya. Berikut penyebab yang akan Anda temui:
Connection refused: koneksi TCP ditolak, sehingga tidak ada yang listening pada port tersebut. sshd berhenti, atau SSH dipindahkan ke port lain sementara inventory Anda masih menggunakan 22.Connection timed out: tidak ada respons sama sekali. Firewall membuang paket, atau server mati. Setiap percobaan menghabiskan seluruh batas waktu koneksi, yaitu 10 detik secara default.Host key verification failed.: key di~/.ssh/known_hoststidak cocok dengan key yang diberikan server. VPS yang dibangun ulang mempertahankan alamat IP-nya dan mendapatkan host key baru. Kondisi ini wajar setelah reinstall, tetapi perlu dianggap serius pada waktu lainnya.Permission denied (publickey): SSH merespons dan menolak key Anda. Port berfungsi dengan baik. Masalahnya adalah autentikasi, biasanya karenaansible_useryang salah atau key yang belum dimuat.Timeout (12s) waiting for privilege escalation prompt: koneksi berhasil, tetapibecometidak berhasil. sudo menunggu password yang tidak pernah diterima.
Interpreter Python yang tidak tersedia sering dianggap sebagai penyebab dalam daftar tersebut, padahal bukan. SSH berhasil terhubung, sehingga host dapat dijangkau. Modul kemudian tidak memiliki lingkungan untuk menjalankan apa pun:
fatal: [db1]: FAILED! => {"changed": false, "module_stdout": "/bin/sh: 1: /usr/bin/python3: not found\r\n", "msg": "The module failed to execute correctly, you probably need to set the interpreter", "rc": 127}Baris tersebut menyatakan FAILED!, dan rekap menghitungnya sebagai failed. Oleh karena itu, ignore_unreachable tidak akan pernah mengaksesnya. Atur ansible_python_interpreter untuk host tersebut, atau install python3 di dalamnya.
Cara mengabaikan host yang tidak dapat dijangkau dalam sebuah play
Pada tingkat task, keyword ini diletakkan di samping module:
- name: Read the package list, and do not stop if the host is down
ansible.builtin.command: dpkg -l
register: packages
changed_when: false
ignore_unreachable: truePada tingkat play, keyword ini menetapkan nilai default untuk setiap task dalam play. Satu task dapat mengubahnya kembali:
- name: Opportunistic fleet maintenance
hosts: all
ignore_unreachable: true
tasks:
- name: This runs, cannot connect, and the play carries on
ansible.builtin.ping:
- name: This one still ends the play for a host that is down
ansible.builtin.ping:
ignore_unreachable: falsePerubahan yang terjadi di balik layar perlu dipahami. Jika ignore_unreachable ditetapkan, host tidak lagi dikeluarkan dari play. Karena itu, setiap task berikutnya akan kembali mencoba terhubung dan kembali gagal dengan cara yang sama. Setiap percobaan menunggu hingga connection timeout berakhir, yaitu 10 detik kecuali Anda mengubah timeout dalam ansible.cfg. Play yang terdiri atas 20 task dan dijalankan terhadap satu server yang tidak aktif akan menambah sekitar 200 detik pada waktu eksekusi dan 20 baris merah pada log.
Jadi, lakukan pemeriksaan sekali, lalu hentikan host tersebut dengan bersih:
- name: Opportunistic fleet maintenance
hosts: all
gather_facts: false
tasks:
- name: Check that the host answers before doing any work
ansible.builtin.ping:
register: reachable
ignore_unreachable: true
- name: End the play for this host if it never answered
ansible.builtin.meta: end_host
when: reachable.unreachable | default(false)
- name: Gather facts now that the connection is known good
ansible.builtin.setup:
- name: Refresh the package index
ansible.builtin.apt:
update_cache: true
become: trueDengan cara ini, hanya ada satu percobaan koneksi untuk setiap host yang tidak aktif, bukan satu percobaan untuk setiap task. end_host, yang ditambahkan pada Ansible 2.8, mengakhiri play untuk host saat ini tanpa menandainya sebagai gagal. Key unreachable hanya ada pada hasil yang didaftarkan jika koneksi gagal. Dengan demikian, default(false) membuat kondisi tetap valid pada setiap host yang merespons. Pengumpulan fact dinonaktifkan pada tingkat play karena task Gathering Facts implisit dapat menjadi task yang pertama kali menemui koneksi yang bermasalah. Anda ingin pemeriksaan tersebut dilakukan oleh ping yang Anda buat sendiri.
ignore_unreachable adalah keyword play dan keyword task. Letakkan keyword ini di playbook agar dapat dilihat pembaca, bukan di dalam role, karena keyword tersebut menentukan host mana yang boleh tidak dijangkau oleh suatu eksekusi. Pemisahan antara playbook dan role menjelaskan layer yang seharusnya memiliki pengaturan seperti ini.
Mengapa ignore_errors bukan alat yang tepat di sini
Dokumentasi Ansible menjelaskan batasan ini secara tegas. ignore_errors "hanya berfungsi jika task dapat dijalankan dan menghasilkan nilai 'failed'. Opsi ini tidak membuat Ansible mengabaikan error variabel yang tidak terdefinisi, kegagalan koneksi, masalah eksekusi (misalnya paket yang tidak ada), atau error sintaks."
Kegagalan koneksi tidak pernah menjadi hasil task yang memiliki failed: true. Kegagalan tersebut muncul sebagai flag terpisah, lalu Ansible memproses flag itu terlebih dahulu: host dimasukkan ke daftar unreachable dan dikeluarkan dari play. Tambahkan ignore_errors: true ke semua dua belas task dalam sebuah play, dan host dengan port SSH yang tertutup tetap berhenti pada task pertama. Ini adalah kekeliruan yang paling umum dalam hal ini. Periksa playbook lama Anda dengan grep, terutama playbook yang ditulis saat mempelajari cara menulis playbook pertama untuk VPS.
Debug sebelum menonaktifkan pemeriksaan
Penonaktifan pemeriksaan yang menjadi permanen menyebabkan konfigurasi banyak host menyimpang, karena host yang tidak dapat dijangkau juga merupakan host yang tidak ditambal. Ikuti urutan ini terlebih dahulu. Semua perintah di sini hanya membaca.
ansible web2 -i inventory.ini -m ansible.builtin.ping -omenjalankan satu modul pada satu host dan mencetak satu baris.- Tambahkan
-vvvvke perintah yang sama. Ansible mencetak perintah ssh lengkap yang dibuatnya, termasuk user target, port, private key, dan opsi yang diteruskan. - Jalankan perintah ssh tersebut sendiri dengan
-v. Jika ssh biasa tidak dapat terhubung, masalahnya berada di bawah Ansible dan tidak ada kata kunci playbook yang dapat memperbaikinya. - Baca string
msgdan cocokkan dengan daftar di atas.Connection refuseddanConnection timed outmengarah ke dua tempat yang berbeda, masing-masing pada service SSH dan jalur jaringan. - Untuk
Host key verification failed., periksa data yang tersimpan denganssh-keygen -F web2.example.com. Jika server dibuat ulang, hapus entri lama denganssh-keygen -R web2.example.comdan terima key baru setelah mencocokkannya dengan konsol provider. Menetapkanhost_key_checking = Falsediansible.cfgmenghapus error tersebut sekaligus menonaktifkan pemeriksaan yang dapat memberi tahu Anda bahwa mesin lain kini menjawab pada alamat tersebut. - Untuk
Permission denied (publickey), pastikan apa yang menurut Ansible harus digunakan.ansible-inventory -i inventory.ini --host web2mencetak variabel yang berlaku, termasukansible_userdanansible_port. - Jika SSH berfungsi tetapi modul tidak berjalan, periksa interpreter dengan
ansible web2 -m ansible.builtin.raw -a 'command -v python3 || echo none'. Modulrawmenjalankan perintah melalui shell dan tidak memerlukan Python pada target.
Host baru boleh diabaikan setelah langkah tersebut dilakukan, sehingga tindakan itu menjadi keputusan, bukan kebiasaan.
Rekapitulasi menghitung host yang tidak dapat dijangkau secara terpisah, dan CI biasanya tidak mendeteksinya
ansible-playbook menghasilkan kode keluar 0 jika berhasil, 2 jika setidaknya satu host gagal, dan 4 jika setidaknya satu host tidak dapat dijangkau. Kedua nilai tersebut merupakan bit flag dalam source code, sehingga proses dengan satu host yang gagal dan satu host yang tidak dapat dijangkau menghasilkan kode keluar 6. Perintah ansible menghasilkan kode yang sama. Hal ini telah diverifikasi terhadap source code ansible-core pada Agustus 2026.
Sekarang tetapkan ignore_unreachable: true dan jalankan play yang sama dengan tujuh task terhadap host mati yang sama:
PLAY RECAP *********************************************************************
web1 : ok=7 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=7 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=7web2 melaporkan unreachable=0 dan tujuh task ok, lalu proses menghasilkan kode keluar 0. Saat keyword tersebut ditetapkan, Ansible menambahkan penghitung ok dan ignored untuk host tersebut, bukan ke penghitung yang disebutnya dark, yaitu penghitung yang mengisi kolom unreachable. Baris UNREACHABLE! berwarna merah tetap ditampilkan, sehingga log tetap akurat, tetapi rekapitulasi dan kode keluarnya tidak.
Job CI yang menjalankan playbook dan hanya memeriksa $? akan menganggap proses tersebut berhasil, dan tidak ada informasi dalam ringkasannya yang menunjukkan bahwa sebuah mesin tidak pernah diakses. Jadikan pemeriksaan keterjangkauan sebagai langkah tersendiri sebelum play dijalankan:
ansible all -i inventory.ini -m ansible.builtin.ping -oPerintah tersebut mencetak satu baris untuk setiap host dan menghasilkan kode keluar 4 jika ada host yang tidak dapat dijangkau. Dengan demikian, pipeline memiliki kondisi yang dapat menyebabkan kegagalan, dan nama host tercatat dalam log. ping memerlukan interpreter Python yang berfungsi pada target, sehingga pemeriksaan ini membuktikan lebih dari sekadar koneksi. Biasanya, hal itu yang Anda perlukan. Kemudian jalankan playbook dengan ignore_unreachable agar host yang aktif tetap menerima perubahan.
any_errors_fatal dan max_fail_percentage pada batch
Kedua kata kunci play ini menentukan tindakan setelah terjadi masalah pada sebagian fleet. Keduanya memperlakukan host yang tidak dapat dijangkau dengan cara yang berbeda.
any_errors_fatal: true bereaksi terhadap host yang tidak dapat dijangkau. Ansible menyelesaikan task saat ini pada host lain dalam batch, lalu menghentikan play untuk setiap host di dalamnya. Gunakan opsi ini jika eksekusi hanya masuk akal apabila berhasil seluruhnya atau gagal seluruhnya, misalnya saat melakukan perubahan skema secara terkoordinasi.
max_fail_percentage: 30 tidak bereaksi terhadap host yang tidak dapat dijangkau. Pemeriksaan ini membagi jumlah host yang failed dengan ukuran batch. Host yang tidak dapat dijangkau disimpan dalam daftar terpisah, sehingga tidak mengubah angka tersebut. Sepuluh host dengan empat host yang tidak dapat dijangkau tetap melanjutkan eksekusi dengan max_fail_percentage: 10, sedangkan dua host yang gagal menjalankan task akan menghentikan play. Dokumentasi menambahkan satu hal penting: "Persentase yang ditetapkan harus terlampaui, bukan sama dengan." Dengan serial: 4, untuk menghentikan eksekusi setelah dua dari empat host gagal, tulis 49, bukan 50.
Ada satu kondisi ketika host yang tidak dapat dijangkau menghentikan eksekusi dengan sendirinya. Jika semua host dalam batch berstatus failed atau tidak dapat dijangkau, Ansible tidak memiliki host yang dapat diproses dan mengakhiri play dengan NO MORE HOSTS LEFT.
serial: menerapkan perubahan secara bertahap di seluruh fleet
- name: Rolling nginx config update
hosts: webservers
serial: 2
max_fail_percentage: 25
tasks:
- name: Deploy the site config
ansible.builtin.template:
src: site.conf.j2
dest: /etc/nginx/conf.d/site.conf
owner: root
mode: "0644"
become: true
notify: Reload nginx
handlers:
- name: Reload nginx
ansible.builtin.service:
name: nginx
state: reloaded
become: trueserial: 2 menjalankan seluruh play pada dua host, menyelesaikannya, lalu memulai dua host berikutnya. serial: "25%" menyesuaikan skala dengan ukuran grup. Sebuah daftar, serial: [1, 5, 10], merupakan pola canary: satu host terlebih dahulu, lalu lima, kemudian sepuluh, sedangkan host yang tersisa dijalankan dalam batch sebesar ukuran terakhir. max_fail_percentage diukur pada setiap batch, sehingga keduanya bekerja bersama. Jika mesin pertama mengalami kerusakan, proses berhenti sebelum kerusakan menjangkau empat puluh mesin. Inilah yang membuat pengelolaan fleet server Linux dari satu mesin kontrol aman dilakukan dengan satu perintah.
Kapan host yang tidak dapat dijangkau perlu diabaikan, dan kapan tidak
Abaikan host tersebut untuk pekerjaan oportunistis. Proses pengumpulan fakta atau pemeriksaan perubahan konfigurasi setiap jam tidak kehilangan apa pun jika melewati host yang sedang tidak aktif, karena proses berikutnya akan memprosesnya. ignore_unreachable: true pada level play adalah pilihan yang tepat, dipasangkan dengan langkah ping agar nama host yang dilewati tercatat di tempat yang akan dibaca seseorang.
Jangan pernah mengabaikannya dalam proses penerapan patch keamanan. Nilai proses tersebut terletak pada jaminan bahwa setiap host telah mendapatkan perbaikan, sedangkan menyembunyikan status tidak dapat dijangkau mengubah pesan "satu server masih rentan" menjadi ringkasan yang tampak bersih. Host yang tidak dapat dijangkau selama dua minggu kemungkinan besar adalah host yang paling tertinggal. Biarkan proses tersebut keluar dengan kode 4 dan biarkan seseorang memeriksanya.
Satu aturan berlaku untuk kedua kasus: hentikan penghentian proses, tetapi jangan hilangkan catatannya. Jika sebuah host dilewati, harus ada keterangan mengenai hal itu, baik dalam ringkasan, log CI, maupun peringatan monitoring. Ansible hanya mengetahui bahwa sebuah host ada selama beberapa detik saat play dijalankan terhadapnya. Karena itu, Ansible bukan tempat yang tepat untuk mengetahui bahwa sebuah server telah tidak aktif sejak hari Selasa. Tugas tersebut merupakan tanggung jawab monitoring, dan playbook Ansible yang menginstal Zabbix dapat menyediakan tampilan seluruh fleet dalam satu sore.
FAQ
Apa perbedaan antara ignore_errors dan ignore_unreachable di Ansible?
ignore_errors: true berlaku untuk task yang berjalan pada host dan mengembalikan kegagalan, misalnya perintah berakhir dengan kode non-zero. ignore_unreachable: true berlaku untuk host yang tidak dapat terhubung oleh Ansible sehingga tidak ada module yang dijalankan. Keduanya membaca field yang berbeda pada hasil task, dan masing-masing tidak mencakup kasus lainnya. Dokumentasi Ansible menyatakan bahwa ignore_errors "tidak membuat Ansible mengabaikan error variabel yang tidak terdefinisi, kegagalan koneksi, masalah eksekusi (misalnya package yang tidak ada), atau error sintaks", dan port SSH yang tertutup merupakan kegagalan koneksi.
Apakah ignore_unreachable menyembunyikan host dari rekap play?
Secara efektif, ya. Jika keyword tersebut ditetapkan, Ansible berhenti menghitung host itu sebagai unreachable dan menghitungnya sebagai ok serta ignored satu kali untuk setiap task, lalu eksekusi berakhir dengan kode 0. Baris fatal: [host]: UNREACHABLE! tetap ditampilkan, sehingga log tetap akurat meskipun rekap dan kode keluar tidak mencerminkan kondisi tersebut. Periksa kolom ignored, atau jalankan ansible all -m ansible.builtin.ping -o sebagai langkah terpisah agar host yang tidak dapat dijangkau tetap menghasilkan kode keluar non-zero pada suatu tahap.
Kode keluar apa yang dikembalikan ansible-playbook ketika sebuah host tidak dapat dijangkau?
ansible-playbook mengembalikan 4. Eksekusi dengan setidaknya satu host yang gagal mengembalikan 2, dan kedua nilai tersebut merupakan bit flag, sehingga eksekusi dengan host yang gagal dan host yang tidak dapat dijangkau mengembalikan 6. Eksekusi yang berhasil tanpa masalah mengembalikan 0. Kode-kode ini diperiksa terhadap source ansible-core pada August 2026. Menetapkan ignore_unreachable: true menghilangkan nilai 4, sehingga pipeline yang hanya menguji kode keluar tidak dapat mendeteksi mesin yang dilewati.
Bagaimana cara melewati sisa play untuk host yang tidak pernah merespons?
Jadikan task pertama ansible.builtin.ping dengan ignore_unreachable: true dan register: reachable, lalu lanjutkan dengan ansible.builtin.meta: end_host menggunakan kondisi when: reachable.unreachable | default(false). end_host mengakhiri play untuk host tersebut tanpa menandainya sebagai gagal. Tetapkan gather_facts: false pada play agar ping Anda menjadi task yang menangani koneksi yang bermasalah. Tanpa pola ini, host yang tidak aktif tetap berada dalam play, dan setiap task berikutnya kembali menunggu hingga connection timeout berakhir.
Apakah host yang tidak dapat dijangkau sebaiknya diabaikan saat menjalankan security patch?
Tidak. Security patch perlu dijalankan karena memberikan jaminan bahwa setiap host telah menerima update. Mengabaikan host yang tidak dapat dijangkau mengganti jaminan tersebut dengan rekap berstatus berhasil. Biarkan eksekusi berakhir dengan kode 4, catat nama host yang tidak merespons, lalu perbaiki masalahnya. Penekanan error hanya sesuai untuk eksekusi berulang yang bersifat oportunistik, karena eksekusi berikutnya akan menangani host yang terlewat.