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