UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh"}
UNREACHABLE! => {"changed": false, "msg": "Authentication failure"}
排查的步驟:
# 第一步:先確認基本連線
ansible all -i inventory.ini -m ping
# 第二步:用 SSH 手動連看看
ssh -v user@target-server
# 第三步:檢查 inventory 設定
ansible-inventory -i inventory.ini --list
💡 Tips:我現在習慣先用 ssh-copy-id 把金鑰複製到所有機器,可以省掉很多麻煩。
FAILED! => {"msg": "Missing sudo password"}
FAILED! => {"msg": "User is not in the sudoers file"}
# 養成好習慣
- name: Install packages
package:
name: nginx
state: present
become: yes # 筆者建議:所有系統操作都要加這個
become_user: root # 明確指定用戶
become_method: sudo # 明確指定方法
FAILED! => {"msg": "AnsibleUndefinedVariable: 'database_host' is undefined"}
# 善用 jinja2 的特性,可以加上 default 值,就不會一直遇到這個問題了
- name: 連接資料庫
mysql_user:
name: "{{ app_user }}"
host: "{{ database_host | default('localhost') }}"
password: "{{ db_password | default('changeme') }}"
ansible-playbook site.yml -v # 平常測試用這個就夠
ansible-playbook site.yml -vv # 出問題時用這個
ansible-playbook site.yml -vvv # 複雜問題必用,超詳細
ansible-playbook site.yml -vvvv # 絕招,什麼都看得到 (但輸出有點多)
筆者的實戰範例:
# 當筆者遇到莫名其妙的錯誤時,一定會這樣做
ansible-playbook -i production deploy.yml -vvv --limit problematic-server
# 通常看了詳細輸出就知道問題在哪了
---
- name: Debug Sample
hosts: all
tasks:
- name: 收集系統資訊
setup:
register: system_info
- name: 顯示筆者關心的系統資訊
debug:
msg:
- "主機名稱: {{ inventory_hostname }}"
- "IP 位址: {{ ansible_default_ipv4.address }}"
- "系統版本: {{ ansible_distribution }} {{ ansible_distribution_version }}"
- "記憶體大小: {{ ansible_memtotal_mb }}MB"
- name: 檢查設定檔是否存在
stat:
path: /etc/nginx/nginx.conf
register: nginx_config
# 小技巧:用 verbosity 控制輸出層級
- name: 顯示檔案狀態詳情
debug:
var: nginx_config
verbosity: 2 # 只有用 -vv 以上才會顯示,避免輸出太雜亂
- name: 筆者的條件式除錯
debug:
msg: "太好了!Nginx 設定檔存在且可讀取 🎉"
when: nginx_config.stat.exists and nginx_config.stat.readable
筆者現在執行任何 Playbook 之前,都會先用檢查模式跑一遍:
# 1. 先檢查會做什麼改變 (超重要!)
ansible-playbook site.yml --check
# 2. 看看具體會改什麼檔案 (筆者必做)
ansible-playbook site.yml --check --diff
# 3. 只檢查特定部分 (筆者常用技巧)
ansible-playbook site.yml --check --tags database
# 筆者現在都會在 Playbook 裡加入這種檢查
- name: 筆者的服務狀態檢查
service_facts:
register: service_status
- name: 確認關鍵服務正常運行
assert:
that:
- "'nginx.service' in service_status.ansible_facts.services"
- "service_status.ansible_facts.services['nginx.service'].state == 'running'"
fail_msg: "慘了!Nginx 服務掛了 😱"
success_msg: "太好了!Nginx 服務正常運行 ✅"
# 只在特定群組執行 (安全第一)
ansible-playbook site.yml --limit web-servers
# 只在出問題的機器執行 (筆者最愛用這招)
ansible-playbook site.yml --limit "web-01,web-02"
# 使用模式匹配 (很方便)
ansible-playbook site.yml --limit "web-*"
# 排除特定機器 (當某台機器有問題時超好用)
ansible-playbook site.yml --limit "all:!problematic-server"
v
等級來找問題debug
模組來追蹤變數值明天來聊聊安全性!