如何编写具有多个任务的Ansible处理程序?

tim*_*els 66 handler ansible

为了响应更改,我有多个应该运行的相关任务.如何编写具有多个任务的Ansible处理程序?

例如,我想要一个仅在已经启动时重启服务的处理程序:

- name: Restart conditionally
  shell: check_is_started.sh
  register: result

- name: Restart conditionally step 2
  service: name=service state=restarted
  when: result
Run Code Online (Sandbox Code Playgroud)

小智 73

从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"
Run Code Online (Sandbox Code Playgroud)

这种使用使得触发多个处理程序变得更加容易.它还将处理程序与其名称分离,使得在剧本和角色之间共享处理程序变得更加容易

具体到这个问题,这应该工作:

- 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
Run Code Online (Sandbox Code Playgroud)

在任务中,通过'重启进程'通知处理程序

http://docs.ansible.com/ansible/playbooks_intro.html#handlers-running-operations-on-change

  • 多个任务是否按列出的顺序执行?如果一个任务依赖于另一任务,我应该在处理程序中使用notify-listen吗? (3认同)
  • 该解决方案是否允许使用 block: 和rescue: 通过启动命令来处理错误? (2认同)
  • 来自链接文档的@user26767:`通知处理程序始终按照它们定义的顺序运行,而不是按照通知语句中列出的顺序运行。使用listen 的处理程序也是如此。 (2认同)

tim*_*els 52

在处理程序文件中,使用notify将不同的步骤链接在一起.

- 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
Run Code Online (Sandbox Code Playgroud)

然后从任务中引用它notify: Restart conditionally.

请注意,您只能通知当前处理程序以下的处理程序.所以例如,Restart conditionally step 2无法通知Restart conditionally.

资料来源:irc.freenode.net上的#ansible.我不确定这是否会在将来继续有效,因为官方文档中没有提到它.

  • 此方法有助于解决似乎很少有文献支持的事实:处理程序一旦收到通知,即使其中一个处理程序失败,也会执行。如果您不希望出现这种情况,那么对于您可能不希望在先前处理程序失败时运行的标签使用不同的“通知”标签是“修复”此问题的好方法。 (4认同)

Ale*_*uer 27

从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
Run Code Online (Sandbox Code Playgroud)

那么你的处理程序就是:

- name: Restart conditionally
  include: restart_tasks.yml
Run Code Online (Sandbox Code Playgroud)

来源:github上的问题线程:https://github.com/ansible/ansible/issues/14270

  • 只是注意到2.0.2和2.1.2之间的Ansible版本有一个不起作用的错误:https://github.com/ansible/ansible/issues/15915 (5认同)
  • 对于未来的读者 - 这对我在 Ansible 2.9.2 上不起作用。修复方法是将“include”替换为“include_tasks”。 (2认同)