使用 Ansible 记住命令之前成功执行的最佳方法是什么?

With Ansible what is the best way of remembering a command has executed successfully previously?

使用command module,如果该命令创建了一个文件,您可以检查该文件是否存在。如果是这样,它会阻止命令再次执行。

- command: touch ~/myfile
  args:
    creates: ~/myfile

但是,如果该命令没有创建文件,那么它会再次执行运行。

为了避免第二次执行,我创建了一些关于更改(通知)的随机文件,如下所示:

- command: dothisonceonly # this does not create a file
  args:
    creates: ~/somefile
  notify: done

然后处理程序:

- name: done
  command: touch ~/somefile

这种方法可行,但有点难看。任何人都可以放弃最佳实践吗?也许设置一些事实?也许是一种全新的方法?

一个命令在特定目标主机上运行成功是事实(通俗地说),所以最合适的是使用local facts(Ansible 白话)。

在您的处理程序中,使用 copy 模块和 content 参数将状态保存为 /etc/ansible/facts.d 下的 JSON 文件。

只要您 运行 通过常规 fact-gathering 流程与主机对战,它就会被检索和访问。

然后你可以用when条件来控制任务(你需要包括default过滤器来过滤没有事实存在的情况)。

理想情况下,使用 Ansible 检查第一个命令更改的状态,而不是使用文件作为代理。原因是检查某物的实际状态提供了更好的不变性,因为它在每次通过时都经过测试。

如果有理由不使用该方法。然后注册命令的结果并使用它而不是通知程序来触发文件的创建。

- command: dothisonceonly # this does not create a file
  creates: ~/somefile
  register: result

- file:
    path: ~/somefile
    state: touch
  when: result|succeeded

如果您想知道这里发生了什么,请添加:

- debug: var=result

请注意通知者,他们 运行 在播放结束时。这意味着如果一个通知程序被一个任务触发但随后播放失败,则通知程序将不会是 运行。相反,有一些 Ansible 选项会导致通知程序 运行,即使不是由任务触发也是如此。

这是我根据@techraf

的回答实际实现的
- command: echo 'phew'
  register: itworks
  notify: Done itworks
  when: ansible_local.itworks | d(0) == 0

和处理程序:

- name: Done itworks
  copy:
    content: '{{ itworks }}'
    dest: /etc/ansible/facts.d/itworks.fact

文档:

http://docs.ansible.com/ansible/playbooks_variables.html#local-facts-facts-d

感谢@techraf 这很好用并且坚持事实。

编辑

在@techraf 的评论中应用了默认值逻辑。