如何配置“全有或全无”的Ansible剧本?

时间:2016-09-02 21:09:56

标签: ansible

我有一堆需要频繁修补的服务器。我打算使用Ansible来协调修补过程。这里的要点是它必须是“全有或全无”修补。所有服务器都已修补或没有。

我正在为我的剧本考虑的任务是这样的: 1 - 转到所有服务器并拍摄lvm快照 2 - IIF任务1适用于所有服务器,应用更改 3 - 如果其中一个主机因任何原因发生故障,请在所有节点上回滚快照。

问题是我是Ansible的新手,我无法在剧本上表达这一点。我写过这个简单的测试手册:

---
- hosts: all
  strategy: linear

  tasks:
  - block:
      - debug: msg='Testing on {{ inventory_hostname }}...'
      - command: /home/amirsamary/activity.sh
        changed_when: false
    rescue:
      - debug: msg='Rollback of {{ inventory_hostname }}...'
  - debug: msg='I continued running tasks on {{ inventory_hostname }}...'

我的广告资源中有两个主机。在第一个节点上,activity.sh返回true,在第二个节点上,activity.sh返回false。因此,node2将始终失败。问题是救援任务只会针对发生故障的主机而不是针对所有主机运行(正如人们所期望的那样)并且剧本继续运行其他任务。

我听说过很多关于Ansible在数千台服务器上协调复杂任务的好处。但我似乎无法找到一种安全实施“全有或全无策略”的方法。我错过了什么?

1 个答案:

答案 0 :(得分:3)

我打赌有很多方法可以实现这一点,其中之一是:

---
- hosts: all
  strategy: linear

  tasks:
    - debug: msg='Testing on {{ inventory_hostname }}...'
    - command: /home/amirsamary/activity.sh
      register: cmd_result
      ignore_errors: true
    - debug: msg='Rollback of {{ inventory_hostname }}...'
      when: play_hosts | map('extract', hostvars, 'cmd_result') | selectattr('failed','defined') | list | count > 0

这里做了什么?

  • 我们将脚本执行的结果注册到cmd_result并忽略错误(如果有的话)
  • 使用线性策略,我们将在下一个任务执行之前在所有主机上完成command任务
  • 所以我们为每个主机注册了cmd_result
  • 检查我们是否需要回滚,我们为当前播放中的所有主机提取cmd_result个事实,选择定义了failed的那些,将它们转换为列表并计算它们:如果有,则回滚

因此,如果任何主机的cmd_result失败,将对所有主机执行回滚任务。

您可能希望在回滚任务后添加此任务:

- fail: msg='Patch command failed!'
  when: cmd_result | failed

这样您就可以完成回滚任务,并将问题主机标记为失败。