如何配置“全有或全无"?Ansible 剧本? [英] How can I configure an "all or nothing" Ansible playbook?

查看:16
本文介绍了如何配置“全有或全无"?Ansible 剧本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆需要经常修补的服务器.我计划使用 Ansible 来协调修补过程.这里的要点是它必须是全有或全无"修补.要么所有服务器都打补丁,要么没有.

I have a bunch of servers that need will be need frequent patching. I am planning on using Ansible to coordinate the patching process. The keep point here is that it must be an "all or nothing" patching. Either all servers are patched or none.

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

The tasks I was considering for my playbook would be something like: 1 - Go to all servers and take an lvm snapshot 2 - IIF task 1 works on all servers, apply the changes 3 - If one of the hosts fails for any reason, roll back the snapshot on ALL NODES.

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

The problem is that I am new to Ansible and I can't express this on a playbook. I have written this simple testing playbook:

---
- 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 将始终失败.问题是救援任务只会为发生故障的主机运行,而不是为所有主机运行(正如人们所期望的那样),并且剧本会继续运行其他任务.

I have two hosts on my inventory. On the first node, activity.sh returns true and on the second node, activity.sh returns false. So, node2 will always fail. The problem is that the rescue tasks will only run for the failed host and not for all of them (as one would expect anyway) and the playbook keeps running the other tasks.

我听说过很多关于 Ansible 在数千台服务器上编排复杂任务的出色之处.但我似乎无法找到一种方法来安全地实施全有或全无策略".我错过了什么?

I have heard a lot about how good Ansible was to orchestrate complex tasks on thousands of servers. But I can't seem to find a way of safely implement an "all or nothing strategy" with it. What am I missing?

推荐答案

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

I bet there are many ways to implement this, here is one of them:

---
- 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 的,将它们转换为列表并计算它们:如果有,回滚.
  • we register result of script execution into cmd_result and ignore errors, if any
  • with linear strategy, we will have command task completed on all hosts before next task being executed
  • so we have cmd_result registered for every host
  • to check if we need to rollback we extract cmd_result facts for all hosts in the current play, select those with failed defined, convert them to list and count them: if there is any, rollback.

因此,如果其中任何一个cmd_result失败,所有主机都会执行回滚任务.

So rollback task will be executed for all hosts if there is failed cmd_result for any of them.

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

You may want to add this task after rollback task:

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

通过这种方式,您将完成回滚任务并将问题主机标记为失败.

This way you will have your rollback tasks done and also mark problem hosts as failed.

这篇关于如何配置“全有或全无"?Ansible 剧本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆