针对变化,我有多个相关任务需要运行。如何编写具有多个任务的Ansible处理程序?
例如,我想要一个仅在服务已启动时才重新启动服务的处理程序:
- name: Restart conditionally
shell: check_is_started.sh
register: result
- name: Restart conditionally step 2
service: name=service state=restarted
when: result
从 Ansible 2.2 开始,此问题已有适当的解决方案。
处理程序也可以“监听”通用主题,并且任务可以按以下方式通知这些主题:
handlers:
- name: restart memcached
service: name=memcached state=restarted
listen: "restart web services"
- name: restart apache
service: name=apache state=restarted
listen: "restart web services"
tasks:
- name: restart everything
command: echo "this task will restart the web services"
notify: "restart web services"
使用此方法可以更轻松地触发多个处理程序。它还将处理程序与其名称解耦,使在playbooks和roles之间共享处理程序变得更加容易。
具体到问题,这应该可行:
- name: Check if restarted
shell: check_is_started.sh
register: result
listen: Restart processes
- name: Restart conditionally step 2
service: name=service state=restarted
when: result
listen: Restart processes
在任务中,通过“重启进程”通知处理程序。
https://docs.ansible.com/ansible/latest/user_guide/playbooks_handlers.html#naming-handlers
- name: Restart conditionally
debug: msg=Step1
changed_when: True
notify: Restart conditionally step 2
- name: Restart conditionally step 2
debug: msg=Step2
changed_when: True
notify: Restart conditionally step 3
- name: Restart conditionally step 3
debug: msg=Step3
然后在一个任务中使用notify: Restart conditionally
进行引用。
请注意,您只能通知当前处理程序以下的处理程序。例如,Restart conditionally step 2
无法通知Restart conditionally
。
来源:在irc.freenode.net上的#ansible频道。我不确定这是否将来会继续有效,因为它在官方文档中没有被提及作为一个特性。
编辑:如果您拥有 Ansible 2.2 或以上版本,请使用 mkadan 的答案。下面的答案不适用于较新版本的 Ansible。另请注意,根据 Enis Afgan 在下面的评论中所述,由于一个错误,该答案在 2.0.2 到 2.1.2 版本的 Ansible 中无效。
从 Ansible 2.0 开始,您可以在处理程序中使用 include 动作来运行多个任务。
例如,将您的任务放入单独的文件 restart_tasks.yml
中(如果您使用角色,则会放入 tasks 子目录中,而不是 handlers 子目录中):
- name: Restart conditionally step 1
shell: check_is_started.sh
register: result
- name: Restart conditionally step 2
service: name=service state=restarted
when: result
你的处理程序将会是:
- name: Restart conditionally
include: restart_tasks.yml
来源:GitHub 上的问题线程:https://github.com/ansible/ansible/issues/14270
include
替换为 include_tasks
。 - Martin Melka
include_role
一起使用时,listen
存在缺陷,处理程序会被执行多次而不是一次。该问题在Ansible核心版本2.11.4中仍然存在。请参见:https://github.com/ansible/ansible/issues/49371 - Personlisten:
参数可以相同,但- Name:
必须不同。 - undefined