Ansible-Playbook异常处理
1、异常处理说明
在 playbook 执行的过程中,难免会遇到一些错误。由于 playbook 遇到错误后,不会执行之后的任务,不便于调试,此时,可以使用 ignore_errors 来暂时忽略错误,使得 playbook 继续执行。
2、示例1-Playbook错误忽略
2.1、编写 playbook 【当有 task 执行失败则会立即终止后续 task 运行】
cat << 'CAT_END' > ignore.yaml - hosts: all remote_user: root tasks: - name: Ignore False command: /bin/false ignore_errors: yes - name: touch test.txt file: path=/tmp/test.txt state=touch CAT_END
2.2、执行 playbook 【使用ignore_errors: yes会报错,后续的任务正常执行】
]# ansible-playbook ignore.yaml PLAY [all] *************************************************************************************************************************************************** TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.10.15] TASK [Ignore False] ****************************************************************************************************************************************** fatal: [192.168.10.15]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.008390", "end": "2023-05-13 22:44:16.521903", "msg": "non-zero return code", "rc": 1,
"start": "2023-05-13 22:44:16.513513", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} ...ignoring TASK [touch test.txt] **************************************************************************************************************************************** changed: [192.168.10.15] PLAY RECAP *************************************************************************************************************************************************** 192.168.10.15 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
3、示例2-task执行失败强制调用handlers
3.1、说明
通常情况下,当 task 失败后, play 将会终止,任何在前面已经被 tasks notify的 handlers 都不会被执行。如果你在 play 中设置了 force_handlers: yes 参数,被通知的 handlers 就会被强制执行。(有些特殊场景可能会使用到)
3.2、编写 playbook
cat << 'CAT_END' > force_handlers.yaml - hosts: httpd force_handlers: yes tasks: - name: Touch File file: path=/tmp/handler_test state=touch notify: restart nginx server - name: install package yum: name=test state=latest handlers: - name: restart nginx server systemd: name=nginx state=restarted CAT_END
3.3、执行playbook
]# ansible-playbook force_handlers.yaml PLAY [httpd] ************************************************************************************************************************************************* TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.10.18] ok: [192.168.10.17] TASK [Touch File] ******************************************************************************************************************************************** changed: [192.168.10.17] changed: [192.168.10.18] TASK [install package] *************************************************************************************************************************************** fatal: [192.168.10.17]: FAILED! => {"changed": false, "msg": "No package matching 'test' found available, installed or updated", "rc": 126, "results": ["No package matching 'test' found available, installed or updated"]} fatal: [192.168.10.18]: FAILED! => {"changed": false, "msg": "No package matching 'test' found available, installed or updated", "rc": 126, "results": ["No package matching 'test' found available, installed or updated"]} # 前者task报错,也不影响handlers的调用 RUNNING HANDLER [restart nginx server] *********************************************************************************************************************** changed: [192.168.10.17] changed: [192.168.10.18] PLAY RECAP *************************************************************************************************************************************************** 192.168.10.17 : ok=3 changed=2 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 192.168.10.18 : ok=3 changed=2 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
4、示例3-控制Tasks报告状态为OK
4.1、编辑 playbook
cat << 'CAT_END' > change_status.yaml - hosts: httpd force_handlers: yes tasks: - name: get nginx server port shell: netstat -tunlp | grep nginx register: nginx_port - name: out nginx server status debug: msg={{nginx_port.stdout_lines}} ignore_errors: yes CAT_END
4.2、执行playbokk
]# ansible-playbook change_status.yaml PLAY [httpd] ************************************************************************************************************************************************* TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.10.18] ok: [192.168.10.17] TASK [get nginx server port] ********************************************************************************************************************************* changed: [192.168.10.18] changed: [192.168.10.17] # 发现这里没有状态 TASK [out nginx server status] ******************************************************************************************************************************* ok: [192.168.10.17] => { "msg": [ "tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 20372/nginx: master ", "tcp6 0 0 :::80 :::* LISTEN 20372/nginx: master " ] } ok: [192.168.10.18] => { "msg": [ "tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 54183/nginx: master ", "tcp6 0 0 :::80 :::* LISTEN 54183/nginx: master " ] } PLAY RECAP *************************************************************************************************************************************************** 192.168.10.17 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.10.18 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.3、shell 任务不应该每次都报告 changed 状态,因为它没有在被管理主机执行后发生变化
# 添加 changed_when: false 来抑制这个改变 cat << 'CAT_END' > change_when_status.yaml - hosts: httpd force_handlers: yes tasks: - name: get nginx server port shell: netstat -tunlp | grep nginx register: nginx_port changed_when: false # 关闭change提示 - name: out nginx server status debug: msg={{nginx_port.stdout_lines}} ignore_errors: yes CAT_END
4.4、执行playbook
]# ansible-playbook change_when_status.yaml PLAY [httpd] ************************************************************************************************************************************************* TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.10.17] ok: [192.168.10.18] TASK [get nginx server port] ********************************************************************************************************************************* ok: [192.168.10.17] ok: [192.168.10.18] # 发现状态,已经变ok TASK [out nginx server status] ******************************************************************************************************************************* ok: [192.168.10.17] => { "msg": [ "tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 20372/nginx: master ", "tcp6 0 0 :::80 :::* LISTEN 20372/nginx: master " ] } ok: [192.168.10.18] => { "msg": [ "tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 54183/nginx: master ", "tcp6 0 0 :::80 :::* LISTEN 54183/nginx: master " ] } PLAY RECAP *************************************************************************************************************************************************** 192.168.10.17 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.10.18 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
5、示例4-changed_when检查任务结果
5.1、httpd-playbook
cat <<'CAT_END'>change_when.yaml - hosts: httpd tasks: - name: configure httpd server template: src=./httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf notify: restart httpd server - name: check httpd syntax shell: /usr/sbin/httpd -t register: httpd_check change_when: - httpd_check.stdout.find('OK') # 查找变量返回的结果是否有ok,如不存在则终止该tasks - false # 被管理主机没有发生变化状态则为OK - name: start httpd server systemd: name=httpd state=present enabled=yes handlers: - name: restart httpd server systemd: name=httpd state=restarted CAT_END
5.2、nginx-playbook
cat <<'CAT_END'>change_when.yaml - hosts: httpd tasks: - name: install nginx server yum: name=nginx state=present - name: configure nginx server template: src=./nginx.conf.j2 dest=/etc/nginx/nginx.conf notify: restart nginx server - name: check nginx syntax shell: /usr/sbin/nginx -t register: nginx_check change_when: - nginx_check.stdout.find('successful') # 查找变量返回的结果是否有ok,如不存在则终止该tasks - false # 被管理主机没有发生变化状态则为OK - name: start nginx server systemd: name=nginx state=present enabled=yes handlers: - name: restart nginx server systemd: name=nginx state=restarted CAT_END