实施处理程序
ansible处理程序
- Ansible模块设计为具有幂等性。这表示,在正确编写的playbook中,playbook及其任务可以运行多次而不会改变受管主机,除非需要进行更改使受管主机进入所需的状态。
- 更改服务配置文件时可能要求重启服务以便使其更改的配置生效。
- 仅当任务在受管主机上更改(change)了某些内容时,任务才通知其处理程序。
- 每个处理程序具有全局唯一的名称
- 如果没有任务通过名称通知处理程序,处理程序就不会运行
- 如果一个或多个任务通知处理程序,处理程序就会在play中的所有其他任务完成后运行一次
- 通常而言,处理程序被用于重新引导主机和重启服务
- 处理程序可视为非活动任务,只有在使用notify语句显式调用时才会被触发
//测试handlers
[root@192 playbook]# vim test.yml
---
- hosts: 192.168.218.128
gather_facts: no
tasks:
- name: install service
yum:
name: vsftpd
state: present
- name: config
copy:
src: files/vsftpd.conf
dest: /etc/vsftpd/vsftpd.conf
notify: restart service
- name: start service
service:
name: vsftpd
state: started
handlers:
- name: restart service
service:
name: vsftpd
state: restarted
//现在没有改动配置文件,执行一次看一下是否handlers执行了
[root@192 playbook]# ansible-playbook test.yml
PLAY [192.168.218.128] ********************************************************************
TASK [install service] ********************************************************************
ok: [192.168.218.128]
TASK [config] *****************************************************************************
ok: [192.168.218.128]
TASK [start service] **********************************************************************
changed: [192.168.218.128]
PLAY RECAP ********************************************************************************
192.168.218.128 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
//因为没有改动配置文件,所以执行的时候handlers没有执行
//现在改动配置文件里的内容,有所改变,然后在执行,看一下是否执行handlers
[root@192 playbook]# ansible-playbook test.yml
PLAY [192.168.218.128] ********************************************************************
TASK [install service] ********************************************************************
ok: [192.168.218.128]
TASK [config] *****************************************************************************
changed: [192.168.218.128]
TASK [start service] **********************************************************************
ok: [192.168.218.128]
RUNNING HANDLER [restart service] //handlers已经执行了,因为有change*********************************************************
changed: [192.168.218.128]
PLAY RECAP ********************************************************************************
192.168.218.128 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
//总结:
1.handlers级别和tasks级别一样
2.handlers执行的顺序是按照下面写的任务顺序来执行
3.handlers执行的前提是要有notify否则不执行
4.再有notify的情况下,handlers执行的条件是必须要有change才执行,否则不执行
使用处理程序的好处
使用处理程序时需要牢记几个重要事项:
- 处理程序始终按照play的handlers部分指定的顺序运行。它们不按在任务中由notify语句列出的顺序运行,或按任务通知它们的顺序运行。
- 处理程序通常在相关play中的所有其他任务完成后运行。playbook的tasks部分中某一任务调用的处理程序,将等到tasks下的所有任务都已处理后才会运行。
- 处理程序名称存在于各play命名空间中。如果两个处理程序被错误地给予相同的名称,则仅会运行一个。
- 即使有多个任务通知处理程序,该处理程序依然仅运行一次。如果没有任务通知处理程序,它就不会运行。
- 如果包含notify语句的任务没有报告changed结果(例如,软件包已安装并且任务报告ok),则处理程序不会获得通知。处理程序将被跳过,直到有其他任务通知它。只有相关任务报告了changed状态,Ansible才会通知处理程序。
处理任务失败
忽略任务失败
-
默认情况下,任务失败时play会中止
-
可以通过忽略失败的任务来覆盖此行为
-
可以在任务中使用ignore_errors关键字来实现此目的
以下举例安装亮相服务,在编辑playbook时其中一个服务名字写错了,不存在服务,忽略此错误安装,继续安装下一个服务:
//编辑playbook,安装两个服务
[root@192 playbook]# vim test.yml
- hosts: 192.168.218.128
gather_facts: no
tasks:
- name: install service
yum:
name: httpd11
state: present
ignore_errors: yes
yum:
name: vsftpd
state: present
//执行并检查
[root@192 playbook]# ansible-playbook test.yml
[WARNING]: While constructing a mapping from /opt/project/playbook/test.yml, line 5,
column 7, found a duplicate dict key (yum). Using last defined value only.
PLAY [192.168.218.128] ********************************************************************
TASK [install service] ********************************************************************
changed: [192.168.218.128]
PLAY RECAP ********************************************************************************
192.168.218.128 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 //虽然playbook写了一个不存在服务,但是执行过后并没有报错
[root@localhost ~]# rpm -qa |grep vsftpd
vsftpd-3.0.3-34.el8.x86_64
[root@localhost ~]# rpm -qa |grep httpd11
[root@localhost ~]#
//在编写playbook时ignore_errors级别和模块级别一样
任务失败后强制执行处理程序
-
通常而言,如果任务失败并且play在该主机上中止,则收到play中早前任务通知的处理程序将不会运行
-
如果在play中设置force_handlers: yes关键字,则即使play因为后续任务失败而中止也会调用被通知的处理程序
-
下列代码片段演示了如何在play中使用force_handlers关键字,以便在任务失败时也强制执行相应的处理程序:
---
- hosts: 172.16.103.129
force_handlers: yes
tasks:
- name: a task which always notifies its handler
command: /bin/true
notify: restart the database
- name: a task which fails because the package doesn't exist
yum:
name: notapkg
state: latest
handlers:
- name: restart the database
service:
name: mariadb
state: restarted
**注意:**处理程序会在任务报告changed结果时获得通知,而在任务报告ok或failed结果时不会获得通知
指定任务失败条件
- 可以在任务中使用failed_when关键字来指定表示任务已失败的条件
- 通常与命令模块搭配使用,这些模块可能成功执行了某一命令,但命令的输出可能指示了失败
- 可以运行输出错误消息的脚本,并使用该消息定义任务的失败状态。下列代码片段演示了如何在任务中使用failed_when关键字:
tasks:
- name: Run user creation script
shell: /usr/local/bin/create_users.sh
register: command_result
failed_when: "'Password missing' in command_result.stdout"
- fail模块也可用于强制任务失败。上面的场景也可以编写为两个任务:
tasks:
- name: Run user creation script
shell: /usr/local/bin/create_users.sh
register: command_result
ignore_errors: yes
- name: Report script failure
fail:
msg: "The password is missing in the output"
when: "'Password missing' in command_result.stdout"