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


80

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

例如,我希望处理程序仅在已经启动时才重新启动服务:

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

- name: Restart conditionally step 2
  service: name=service state=restarted
  when: result

Answers:


94

从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"

这种用法使触发多个处理程序变得更加容易。它还使处理程序与其名称脱钩,从而使在剧本和角色之间共享处理程序更加容易

专门针对该问题,这应该起作用:

- 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

然后在任务中通过“重新启动流程”通知处理程序

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


1
该解决方案是否允许使用block:和抢救:通过启动命令来处理错误?
user1767316 '18

3
是否按照列出的顺序执行了多个任务?如果一个任务依赖于另一个任务,是否应该在处理程序内部使用notify-listen?
user26767

来自链接文档的@ user26767:Notify handlers are always run in the same order they are defined, not in the order listed in the notify-statement. This is also the case for handlers using listen.
swenzel

55

在处理程序文件中,使用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

然后使用引用该任务notify: Restart conditionally

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

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


此方法可以解决以下事实:文献很少:处理程序一旦被通知,即使其中一个处理程序发生故障也将执行。notify如果先前的处理程序失败,则为那些您不希望运行的标签使用不同的标签是一种“修复”此问题的好方法,如果您不希望这样做的话。
fbicknel

27

编辑: 如果您具有Ansible 2.2或更高版本,请使用mkadan的答案。以下答案不适用于较新版本的Ansible。还要注意,根据下面的Enis Afgan的评论,由于存在错误,此答案不适用于2.0.2和2.1.2之间的Ansible版本。


从Ansible 2.0开始,您可以在处理程序中使用include动作来运行多个任务。

例如,将您的任务放在一个单独的文件中restart_tasks.yml(如果您使用角色,它将进入任务子目录,而不是处理程序子目录):

- 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


5
请注意,在2.0.2和2.1.2之间的Ansible版本有一个无法正常工作的错误:github.com/ansible/ansible/issues/15915
Enis Afgan,

1
对于将来的读者-在Ansible 2.9.2上,这对我不起作用。该修复程序已替换includeinclude_tasks
马丁梅尔卡

@MartinMelka谢谢,我在回答的顶部添加了一个警告,该警告并不表示Ansible版本> = 2.2。
亚历山大·克劳尔

太好了,谢谢:)在设计新的处理程序时,另一个答案更好。但是,当Ansible库存代码过时并且只需要进行少量更改(就像我所做的那样)时,只需添加少量内容就可以使用。
马丁梅尔卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.