如何编写仅在任务文件中的任何先前其他任务更改时运行的Ansible角色任务?

时间:2016-07-01 11:43:27

标签: ansible ansible-role

我正在处理一个角色,我希望在任务文件的末尾运行一个任务,当且仅当该任务文件中先前任务的任何已更改时。

例如,我有:

- name: install package
  apt: name=mypackage state=latest

- name: modify a file
  lineinfile: do stuff

- name: modify a second file
  lineinfile: other stuff

- name: restart if anything changed
  service: name=mypackage state=restarted

...如果已安装更新或任何配置文件已更改,我只想重新启动服务。

我该怎么做?

1 个答案:

答案 0 :(得分:10)

此处的最佳做法是使用handlers

在您的角色中创建一个包含内容的文件handlers/main.yml

- name: restart mypackage
  service: name=mypackage state=restarted

然后从所有任务中通知此处理程序。仅当任务报告已更改状态(=黄色输出)

时,才会通知处理程序
- name: install package
  apt: name=mypackage state=latest
  notify: restart mypackage

- name: modify a file
  lineinfile: do stuff
  notify: restart mypackage

- name: modify a second file
  lineinfile: other stuff
  notify: restart mypackage

处理程序将在游戏结束时执行。如果您涉及其他角色,这取决于重新启动的mypackage服务,您可能希望在角色的末尾刷新所有处理程序:

- meta: flush_handlers

另外,请查看force_handlers设置。如果在mypackge角色之后处理的任何其他角色发生错误,则不会触发处理程序。在force_handlers=True中设置ansible.cfg仍会强制您的处理程序在发生错误后执行。这是一个非常重要的主题,因为当您下次运行您的Playbook时,文件将不会被更改,因此处理程序不会得到通知,因此您的服务永远不会重新启动。

您也可以在没有处理程序的情况下执行此操作,但这非常难看。您需要注册每个任务的输出,以便稍后检查应用于重新启动任务的条件中的状态。

- name: install package
  apt: name=mypackage state=latest
  register: mypackage_1

- name: modify a file
  lineinfile: do stuff
  register: mypackage_2

- name: modify a second file
  lineinfile: other stuff
  register: mypackage_3

- name: restart if anything changed
  service: name=mypackage state=restarted
  when: mypackage_1 is changed or mypackage_2 is changed or mypackage_3 is changed

可以使用mypackage_1 |改为ansible 2.9

另请参阅Ansible Handler notify vs register的答案。