如何确保每个主机只执行一次Ansible shell命令?

时间:2016-07-07 12:02:32

标签: shell ansible

我希望能够保证在给定主机上成功执行长时间运行的shell命令后,它不会在该主机上的后续playbook中执行。

我很高兴得知Ansible shell任务的creates选项(参见http://docs.ansible.com/ansible/shell_module.html);使用这个我可以在shell命令成功后创建一个文件,而不是在将来的运行中执行该命令:

- name: Install Jupiter theme
  shell: wp theme install ~/downloads/jupiter-theme.zip --activate
         && touch ~/ansible-flags/install-jupiter-theme
  args:
    creates: ~/ansible-flags/install-jupiter-theme

如您所见,我的活动用户(ansible-flags)的主目录中有这些控制文件的目录deploy

然而,这是一个相当大的问题。有更好的方法吗?

此外,当我需要以不同的用户身份运行步骤时,情况变得更加复杂;在这种情况下,我无权访问deploy主目录及其子目录。当然,我可以授予访问权限,但这会增加更多的复杂性。你会怎么建议我处理这个?

2 个答案:

答案 0 :(得分:3)

Ansible本身是无国籍的,所以无论你使用什么技术都需要自己实现。没有比告诉Ansible只运行一次任务更简单的方法了。

我认为你已经很直接了。也许用另一条路来检查。我非常确定wp theme install会将该zip实际提取到某个位置,然后您可以将其与creates选项一起使用。

有其他选择,但没有什么可以让它变得更容易:

  • 使用您喜欢的任何语言创建一个脚本,检查主题,如果没有安装,请安装它。您将使用script module执行脚本而不是shell任务。

  • /etc/ansible/facts.d中安装local fact,检查主题是否已安装。然后,您可以简单地将基于该事实的条件应用于shell任务。

  • 设置fact caching,然后注册shell任务的结果并将其存储为事实。启用事实缓存后,您可以在以后的playbook运行中访问存储的结果。

它变得更加复杂。 creates选项非常适合这种情况,如果您使用wp命令提取zip的位置,它也非常干净。

当然,如果您需要从其他用户帐户访问该文件,则需要授予对该文件的访问权限。将内容存储在用户主目录中,权限设置为只能由所有者读取,这确实不是理想的解决方案。

答案 1 :(得分:3)

你的剧本应该是幂等的! 因此,任何一项任务都应该是安全的,可以多次执行(例如echo ok),或者您应该检查是否应该执行它。
您的任务可能如下所示:

- name: Install Jupiter theme
  shell: wp theme is-installed jupiter || wp theme install ~/downloads/jupiter-theme.zip --activate

它将检查是否已安装jupiter主题,并且仅在未安装主题时才会运行wp theme install
但在任何情况下,这都会将任务结果标记为changed 为了做到这一点,你可以这样做:

- name: Install Jupiter theme
  shell: wp theme is-installed jupiter && echo ThemeAlreadyInstalled || wp theme install ~/downloads/jupiter-theme.zip --activate
  register: cmd_result
  changed_when: cmd_result.stdout != "ThemeAlreadyInstalled"

首先,它将检查是否已经安装了木星主题 如果是这种情况,它将输出ThemeAlreadyInstalled并退出 否则会拨打wp theme install 任务的结果已注册到cmd_result 我们使用changed_when参数来说明如果ThemeAlreadyInstalled ansible不应该将任务视为已更改,那么它会在您的剧本输出中保持绿色。

如果您在wp theme install之前执行一些准备任务(例如下载主题),您可能希望将测试作为单独的任务运行以注册结果并在后续任务中使用when子句:

- name: Check Jupiter theme is installed
  shell: wp theme is-installed jupiter && echo Present || echo Absent
  register: wp_theme
  changed_when: false

- name: Download theme
  get_url: url=...
  when: wp_theme.stdout == "Absent"

- name: Install Jupiter theme
  shell: wp theme install ~/downloads/jupiter-theme.zip --activate
  when: wp_theme.stdout == "Absent"