ansible系列(28)--ansible的playbook异常处理
1. playbook的异常处理
1.1 Playbook错误忽略
在 playbook
执行的过程中,难免会遇到一些错误(返回结果不为0)。由于 playbook
遇到错误后,不会执行之后的任务,不便于调试,此时,可以使用 ignore_errors
来暂时忽略错误,使得 playbook
继续执行。
-
首先编写一个
playbook
文件:[root@xuzhichao playbook]# cat ignore.yml - hosts: localhost tasks: - name: Igonre False shell: /bin/false <==此命令返回值一定不为0 - name: Print Message debug: msg: "It's hard to here"
-
此时运行
playbook
时会在Igonre False
任务中报错,无法继续向下运行:[root@xuzhichao playbook]# ansible-playbook ignore.yml PLAY [localhost] ********************************************************************************************************************************************** TASK [Igonre False] ******************************************************************************************************************************************* fatal: [localhost]: FAILED! => {"changed": true, "cmd": "/bin/false", "delta": "0:00:00.024018", "end": "2021-08-05 21:36:36.638534", "msg": "non-zero return code", "rc": 1, "start": "2021-08-05 21:36:36.614516", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} PLAY RECAP **************************************************************************************************************************************************** localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
-
修改
playbook
文件,忽略中间task
的错误,继续向下执行:[root@xuzhichao playbook]# cat ignore.yml - hosts: localhost tasks: - name: Igonre False shell: /bin/false ignore_errors: yes - name: Print Message debug: msg: "It's hard to here"
-
此时运行
playbook
会忽略掉中间task
的错误,继续向下运行:[root@xuzhichao playbook]# ansible-playbook ignore.yml PLAY [localhost] ********************************************************************************************************************************************** TASK [Igonre False] ******************************************************************************************************************************************* fatal: [localhost]: FAILED! => {"changed": true, "cmd": "/bin/false", "delta": "0:00:00.004268", "end": "2021-08-05 21:37:16.630140", "msg": "non-zero return code", "rc": 1, "start": "2021-08-05 21:37:16.625872", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} ...ignoring <==忽略错误 TASK [Print Message] ****************************************************************************************************************************************** ok: [localhost] => { "msg": "It's hard to here" } PLAY RECAP **************************************************************************************************************************************************** localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
-
也可以写成下面的形式来保证
task
的返回值为0
:- hosts: localhost tasks: - name: Igonre False shell: /bin/false || /bin/ture - name: Print Message debug: msg: "It's hard to here"
1.2 task执行失败强制调用handlers
通常情况下,当 task
失败后, playbook
将会终止,任何在前面已经被 tasks notify
的 handlers
都不会被执行。如果你在 playbook
中设置了 force_handlers: yes
参数,被通知的 handlers
就会被强制执行。
-
请看下面的
playbook
:[root@xuzhichao playbook]# cat force_handlers.yml - hosts: localhost tasks: - name: Copy Configure File template: src: conf/nginx.conf.j2 dest: /tmp/nginx.conf notify: Start Nginx - name: Igonre False shell: /bin/false handlers: - name: Start Nginx service: name: nginx state: started
-
当
conf/nginx.conf.j2
文件发生改变时,由于在Igonre False
这个task
中执行出现错误,将不会执行handlers
中的内容。[root@xuzhichao playbook]# ansible-playbook force_handlers.yml PLAY [localhost] ********************************************************************************************************************************************** TASK [Copy Configure File] ************************************************************************************************************************************ ok: [localhost] TASK [Igonre False] ******************************************************************************************************************************************* fatal: [localhost]: FAILED! => {"changed": true, "cmd": "/bin/false", "delta": "0:00:00.006289", "end": "2021-08-05 22:09:40.799988", "msg": "non-zero return code", "rc": 1, "start": "2021-08-05 22:09:40.793699", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} PLAY RECAP **************************************************************************************************************************************************** localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
-
若此时需要强制执行
handlers
中的内容,需要使用force_handlers: yes
参数,playbook
修改如下:[root@xuzhichao playbook]# cat force_handlers.yml - hosts: localhost force_handlers: yes tasks: - name: Copy Configure File template: src: conf/nginx.conf.j2 dest: /tmp/nginx.conf notify: Start Nginx - name: Igonre False shell: /bin/false handlers: - name: Start Nginx service: name: nginx state: started
-
此时运行
playbook
,当conf/nginx.conf.j2
文件发生改变时,handlers
将会被强制执行:[root@xuzhichao playbook]# ansible-playbook force_handlers.yml PLAY [localhost] ********************************************************************************************************************************************** TASK [Copy Configure File] ************************************************************************************************************************************ changed: [localhost] TASK [Igonre False] ******************************************************************************************************************************************* fatal: [localhost]: FAILED! => {"changed": true, "cmd": "/bin/false", "delta": "0:00:00.003843", "end": "2021-08-05 22:12:00.335807", "msg": "non-zero return code", "rc": 1, "start": "2021-08-05 22:12:00.331964", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} RUNNING HANDLER [Start Nginx] ********************************************************************************************************************************* ok: [localhost] PLAY RECAP **************************************************************************************************************************************************** localhost : ok=2 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
1.3 控制Tasks报告状态为OK
有时一些task会在每次playbook运行是都会执行一次,这样会导致playbook的运行结果中该task会显示为changed状态,但是有时这些task并没有改变被控端的状态,仅仅是获取了某些信息,此时可以使用changed_when: false 来抑制这个状态。
请看下面示例:
-
playbook文件内容如下:
[root@xuzhichao playbook]# cat status_ok.yml - hosts: localhost tasks: - name: Get Nginx Server Port shell: netstat -ntlp | grep nginx register: nginx_port - name: Print Nginx Port debug: msg: - "{{ nginx_port.stdout_lines }}"
-
每次的执行结果“Get Nginx Server Port”任务状态都是changed:
[root@xuzhichao playbook]# ansible-playbook status_ok.yml PLAY [localhost] ********************************************************************************************************************************************** TASK [Get Nginx Server Port] ********************************************************************************************************************************** changed: [localhost] <==状态为changed TASK [Print Nginx Port] *************************************************************************************************************************************** ok: [localhost] => { "msg": [ [ "tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 26579/nginx: master " ] ] } PLAY RECAP **************************************************************************************************************************************************** localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
-
可以使用changed_when: false 来抑制这个状态,playbook修改如下:
[root@xuzhichao playbook]# cat status_ok.yml - hosts: localhost tasks: - name: Get Nginx Server Port shell: netstat -ntlp | grep nginx register: nginx_port changed_when: false <==该task不再发生changed提示 - name: Print Nginx Port debug: msg: - "{{ nginx_port.stdout_lines }}"
-
此时执行结果如下:
[root@xuzhichao playbook]# ansible-playbook status_ok.yml PLAY [localhost] ********************************************************************************************************************************************** TASK [Get Nginx Server Port] ********************************************************************************************************************************** ok: [localhost] <==变为OK状态 TASK [Print Nginx Port] *************************************************************************************************************************************** ok: [localhost] => { "msg": [ [ "tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 26579/nginx: master " ] ] } PLAY RECAP **************************************************************************************************************************************************** localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
1.4 changed_when检查任务结果
仍然以安装httpd
为例,在每次修改完httpd
的配置文件后,都需要检查配置文件的语法是否正确,如果不正确,则退出后续task
,不重启httpd
服务。
-
playbook
文件优化如下:[root@xuzhichao playbook]# cat change_when.yml --- - hosts: 192.168.20.23 remote_user: root tasks: - name: Install Htttpd Server yum: name: httpd state: present tags: - install_httpd - install_apache - name: Configure Httpd Server copy: src: conf/httpd.conf.j2 dest: /etc/httpd/conf/httpd.conf owner: "root" group: "root" mode: "0644" notify: Restart Httpd Server tags: conf_httpd - name: Check Httpd Configuer <==检测配置文件语法 shell: /usr/sbin/httpd -t register: httpd_check changed_when: - httpd_check.stdout.find('OK') <==查找变量返回的结果是否有ok,如不存在则终止该tasks - false <==被管理主机没有发生变化状态则为OK - name: Init Httpd Server copy: src: file/test.html.j2 dest: /var/www/html/test.html owner: "apache" group: "apache" mode: "0644" tags: init_httpd - name: Start Httpd Server service: name: httpd state: started enabled: yes tags: start_httpd handlers: - name: Restart Httpd Server service: name: httpd state: restarted tags: restart httpd [root@nginx03 ~]# httpd -t Syntax OK
playbook
运行结果如下:[root@xuzhichao playbook]# ansible-playbook change_when.yml PLAY [192.168.20.23] ****************************************************************************************************************************************** TASK [Install Htttpd Server] ********************************************************************************************************************************** ok: [192.168.20.23] TASK [Configure Httpd Server] ********************************************************************************************************************************* ok: [192.168.20.23] TASK [Check Httpd Configuer] ********************************************************************************************************************************** ok: [192.168.20.23] TASK [Init Httpd Server] ************************************************************************************************************************************** ok: [192.168.20.23] TASK [Start Httpd Server] ************************************************************************************************************************************* changed: [192.168.20.23] PLAY RECAP **************************************************************************************************************************************************** 192.168.20.23 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0