仅在每个主机上第一次运行时执行任务

时间:2021-03-10 21:53:38

标签: ansible

我是 ansible 的新手,我只想运行一些任务一次。不是每次运行一次,而是只有一次,然后永远不会。在 puppet 中,我为此使用了文件占位符,类似于 ansible 的“创建”。

我的用例的最佳实践是什么?

如果我应该使用“creates”方法,哪个文件夹应该可以安全使用?

例如,我想在第一步是更新 snap 的主机上安装 letencrypt。我不想每次运行都刷新 snap,所以我只想在安装 letencrypt 之前运行它。

- name: Update snap
      command: snap install core && snap refresh core
      args:
        creates: /usr/local/ansible/placeholders/.update-snap
      become: true

1 个答案:

答案 0 :(得分:1)

大多数 ansible 模块都是幂等的,这意味着它们只会在需要时执行操作。

shellscriptcommand 是例外,因为 ansible 无法知道是否需要执行操作,这就是为什么有 creates 参数来添加幂等性。

这就是为什么在编写 shell 任务之前,您应该检查是否还没有可以执行您的任务的 ansible 模块。有近 3000 个基础模块,有了新版本的 ansible,您可以通过 Ansible Galaxy 中的集合获得社区提供的新模块。

在您的具体情况下,snap 模块 (https://docs.ansible.com/ansible/2.10/collections/community/general/snap_module.html) 可能就足够了:

- name: Update snap
  snap:
    name: core
  become: true

如果 core snap 尚未安装,它将安装它,否则什么都不做。

如果这还不够,您可以通过创建一个任务查询 snap 来检查 core 的存在及其版本(添加一个 changed_when: False 因为它是一个不做任何更改的任务)来实现自己的幂等性,并且然后根据查询结果启动安装/更新(带有 when 条件)。

如果没有办法做到这一点,那么您可以回退到使用 creates。如果执行的命令已经创建了一个特定文件,可以使用该文件来知道它是否已经执行,最好参考这个文件。否则,您需要在 shell 中创建自己的标记文件。由于它是最后一个选项解决方案,因此没有约定此标记文件应该在哪里,因此由您创建自己的(您建议的那个看起来不错,即使文件名可以更具体并在其中包含快照名称)如果您应该对其他快照使用相同的技巧)。

相关问题