每个主机都“暂停”

udo*_*dan 3 ansible ansible-2.x

在滚动更新之前,我想在监控工具中为每个主机设置停机时间。我为此创建了一个自定义模块。设置停机时间时可能会出现问题,而我们无法解决这些问题。在这种情况下,我想让用户选择是否应该中止部署或在不设置停机时间的情况下继续部署。

假设我这样调用我的模块:

- downtime:
    duration: 5m
    comment: whatever
  ignore_errors: true
  register: downtime
Run Code Online (Sandbox Code Playgroud)

所以我忽略错误才能继续。否则,设置停机时间失败的主机将不会被进一步处理。

在下一步中,我希望用户手动确认是否要对每个未设置停机时间的主机继续操作。

- name: Request user confirmation to proceed in case downtime could not be set
  pause:
    prompt: 'Downtime could not be set for all hosts. Do you want to proceed? Press return to continue. Press Ctrl+c and then "a" to abort'
  when: "{{ downtime | failed }}"
Run Code Online (Sandbox Code Playgroud)

不幸的是,该pause模块(实际上它是一个操作插件)只会在处理的第一个主机上暂停。因此,如果第一台主机失败,它将暂停,如果第一台主机通过并且所有其他主机都失败,它将继续所有主机。

这似乎是预期的行为。来自文档

暂停模块集成到异步/并行化剧本中,无需任何特殊考虑(另请参阅:滚动更新)。当使用带有serialplaybook 参数的暂停时(如滚动更新),系统只会针对当前主机组提示一次。

因此,无论如何,即使我使用serial: 1(在这种情况下不可能)暂停也只会为第一个主机停止。

现在我只是无条件暂停,让用户决定是否继续,无论停机任务是否失败。但由于失败应该非常罕见,这是我想避免的手动步骤。

任何人都可以看到解决方案如何:

  • 每个主机暂停(失败)
  • 暂停一次,以防任何主机出现故障

小智 6

为了pause在一组主机上运行该模块,我采用了以下技巧:

- pause:
    prompt: "{{ item }} will be restarted. Enter 'YES' to restart"
  register: input
  with_items: "{{ play_hosts }}"

- set_fact:
    user_input: "{{ item.user_input }}"
  with_items: "{{ hostvars[play_hosts.0].input.results }}"
  when: item.item == ansible_hostname|upper
Run Code Online (Sandbox Code Playgroud)

正如 udondan 所说,pause模块在组的第一台主机上运行。通过这两项任务,我们获取每个主机的输入,并为所有主机设置一个可用的新事实。