You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible多主机角色失败回滚及跨Play变量传递方案咨询

Ansible 部署失败后的选择性回滚解决方案

需求回顾

需要在Ansible Tower动态生成的all组主机上串行执行部署角色,任意主机部署失败时:

  • 立即终止后续未执行主机的部署流程
  • 对所有已执行过部署的主机(无论成功/失败)统一执行回滚
  • 不依赖hostvars跨Play传递变量

原Playbook的核心问题

  1. successful_hosts是主机级变量,无法跨主机汇总已执行主机列表
  2. any_errors_fatal: true会直接终止整个Play,但未提前标记已执行主机
  3. 回滚Play仅针对失败主机触发,未覆盖成功执行的主机
  4. 任务逻辑存在矛盾(如assert判断条件反向),且变量存储方式无法实现全局共享

修正后的Playbook实现

以下是满足需求的完整Playbook,通过localhost作为全局事实存储节点实现变量共享,避免依赖hostvars:

- name: 执行部署角色并记录已执行主机
  hosts: all
  serial: 1
  max_failure_percentage: 0
  vars_files:
    - ../roles/default/vars.yml
  tasks:
    # 将当前主机标记为已执行,存储到localhost的全局事实中
    - name: 标记主机已进入部署流程
      set_fact:
        host_executed_{{ inventory_hostname }}: true
      delegate_to: localhost
      delegate_facts: true
      run_once: false

    # 执行部署角色序列
    - name: 运行部署角色
      block:
        - include_role:
            name: "{{ role_item }}"
          loop:
            - role_download_artifact
            - role_create_config
            - role_deploy_app
          loop_control:
            loop_var: role_item
      rescue:
        # 标记当前主机部署失败,存储到localhost全局事实
        - name: 标记主机部署失败
          set_fact:
            host_failed_{{ inventory_hostname }}: true
          delegate_to: localhost
          delegate_facts: true
          run_once: false

        # 终止后续所有主机的部署任务
        - name: 终止剩余主机部署流程
          meta: end_play

- name: 对所有已执行主机执行回滚
  hosts: localhost
  vars_files:
    - ../roles/default/vars.yml
  tasks:
    # 从localhost的全局事实中提取所有已执行的主机列表
    - name: 生成已执行主机清单
      set_fact:
        executed_hosts: "{{ hostvars['localhost'] | dict2items | selectattr('key', 'match', 'host_executed_.*') | map('regex_replace', 'host_executed_(.*)', '\\1') | list }}"

    # 遍历已执行主机,逐个执行回滚角色
    - name: 执行回滚操作
      include_role:
        name: role_rollback
      delegate_to: "{{ item }}"
      loop: "{{ executed_hosts }}"

关键逻辑说明

  • 全局事实存储:通过delegate_to: localhost将主机执行状态(host_executed_<hostname>)和失败状态(host_failed_<hostname>)存储在localhost的事实中,实现跨Play的全局共享,完全避免使用hostvars跨主机读取变量
  • 串行执行与终止:serial:1保证逐台执行部署任务,任意主机失败时通过meta: end_play立即终止后续未执行主机的部署
  • 精准回滚范围:从localhost的事实中筛选出所有标记为已执行的主机,对这些主机统一执行回滚,不管部署是否成功
  • 变量传递替代方案:用带主机名后缀的变量名(如host_executed_host1)存储状态,避免数组变量在多主机环境下的冲突问题

注意事项

  • 确保role_rollback角色支持两种场景的回滚:部署成功后的清理、部署失败后的状态恢复
  • Ansible Tower中需确保localhost节点能通过SSH访问所有目标主机(配置对应密钥或认证方式)
  • 若需调整并行度,可修改serial参数,但逐台执行(serial:1)是保证回滚范围精准的最优选择

内容的提问来源于stack exchange,提问作者Sriram Krishnan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:14:51