文章目录
一、处理程序
1. 示例:处理程序
处理程序是响应由其他任务触发的通知的任务
处理程序任务列表的开头:handlers
示例:只有在 template 任务通知已发生更改时才会触发
---
- name: Test
hosts: web
tasks:
- name: Copyt File
template:
src: files/example.conf #需要在当前目录中编写源配置文件
dest: /etc/httpd/conf.d/example.conf
notify: #notify 语句指出该任务需要触发一个处理程序
- restart apache #程序名
- restart mysql
handlers: #表示处理程序任务列表的开头
- name: restart apache #被任务调用的处理程序名称
service: #处理该程序的模块
name: httpd
state: restarted
- name: restart mariadb
service:
name: mariadb
state: restarted
...
使用处理程序要注意:
1. 处理程序始终按照 play 的 handlers 部分指定的顺序运行,不按 notify 里的
2. 处理程序通常在相关 play 中所有其他任务运行完后运行
3. 处理程序名称存在于个 play 命名空间中(如果两个处理程序同名,只会运行一个)
4. 如果多个任务通知处理程序,处理程序也只会运行一次
5. 如果包含 notify 的语句任务没有报告 changed 结果,则处理程序不会获得通知
2. 忽略任务失败
关键字ignore_errors
通常 playbook 遇到错误会中止执行,但是有时我们想要失败时也继续执行。此时可以使用关键字ignore_errors忽略任务失败。
示例: 当要安装一个系统中不存在的软件包时,忽略任务失败
3.任务失败后强制执行处理程序
关键字:force_handlers:yes
通常任务失败,play 会中止,那么收到 play 中止之前任务通知的处理程序将不会运行;如果要运行,需要使用关键字:force_handlers。
处理程序会在任务报告 changed 结果时获得通知,ok 或者 failed 都不会。
示例:
4. 指定任务失败条件
关键字:failed_when
fail 模块可以实现此效果,fail 模块可以提供明确消息
tasks:
- name: Run Script
shell: /usr/local/bin/user.sh
register: command_result
failed_when: "'failure' in command_result.stdout"
#############################使用fail 模块##############################
tasks:
- name: Run Script
shell: /usr/local/bin/user.sh
register: command_result
ignore_error: yes
- name: Report failure
fail:
msg: "Authentication failure" #fail 模块可以提供明确消息
when: "'failure' in command_result.stdout"
5. 指定任务何时报告"Changed"结果
关键字:changed_when:false
简单示例:当执行date命令时,每次都会改变而触发触发器生成changed报告,不想要changed报告就可以添加关键字
- name: get time
shell: date
changed_when: false
二、ansible块和错误处理
1. 三种关键字
(1)block:定义要运行的主要任务
(2)rescue:定义要在 block 子句中定义的任务失败时运行的任务
(3)always:定义始终独立运行的任务
2. 练习:
2.1 当出现错误使用三种关键字解决
此时运行时会报错:第一个任务失败,第二个任务不运行
解决这个问题:
可以直接可以添加忽略关键字:ignore_errors: yes
也可以使用 block、rescue、always 将任务分开
---
- name: Task Failure
hosts: web
vars:
web_pkg: http #此时错误仍然存在
db_pkg: mariadb-server
db_service: mariadb
tasks:
- name: Set up Web
block: #主要任务
- name: Install {{ web_pkg }} packages
yum:
name: "{{ web_pkg }}"
state: present
rescue: #在block子句中定义的任务失败时运行的任务
- name: Install {{ db_pkg }} packages
yum:
name: "{{ db_pkg }}"
state: present
always: #始终运行的任务
- name: Start {{ db_service }} service
service:
name: "{{ db_service }}"
state: started
...
当再次修改,将 http 的包改为正确,发现 rescue 部分被忽略,但是 always 总会执行
2.2 添加控制‘changed’条件
使用关键字changed_when:false
示例:在上述playbook原有基础上添加两个任务,查看并打印时间
运行发现 check time 任务始终是 changed
因为任务没有更改受管主机,所以不应该每次都是 changed。修改文件,添加关键字。再次运行,变为 ok
2.3 改变任务执行状态
使用 failed_when 关键字,改变了任务的执行状态。
示例:在上述playbook基础上添加关键字,改变了任务的执行状态,没有改变任务本身,但是失败的状态可以让 rescue 语句块执行。
三、总结
- 只有任务报告受管主机做了更改,才会通知处理程序
- 处理任务失败,即使成功的任务也可以标记为失败
- 块用于将任务分组为单元,通过任务是否成功来确定执行其他任务与否