当其中一个角色失败时,在多个主机上进行 Ansible 回滚。如何在不同play之间传递变量?

问题描述 投票:0回答:1

我需要在“all”定义的多个服务器上运行一组角色。我不知道服务的名称,因为它们源自 Ansible 塔的动态库存。

如果这些角色中的任何任务失败,我需要在已执行戏剧的所有主机上进行回滚(无论成功与否)。

例如,如果有host1、host2和host3,我在这些主机上执行我的角色。 Host1所有角色都通过。 Host2 一项任务失败,主机被标记为“失败”。主机3也执行失败。

  • 我最好不希望剧本继续执行主机 3 上的角色,因为主机 2 失败了。
  • 我想单独在主机 1 和主机 2 上执行回滚角色,这会将系统恢复到之前的状态。

我创作了两部剧:

首先执行角色,记录失败的主机,并且理想情况下希望在其中一个角色失败时停止在其余主机上的播放。这似乎不会发生。

我想在不使用 Hostvars 的情况下将值传递给第二个播放(因为我不知道执行的主机的名称。

第二次播放,我希望回滚仅发生在已执行的主机上。

- hosts: all
  serial: 1
  max_failure_percentage: 0
  any_errors_fatal: true
  vars:
    successful_hosts: []
  tasks:
    - name: Record successfully executed hosts
      set_fact:
        host_failed: "{{ false if ansible_failed is not defined else ansible_failed }}"
 
    - name: Record successfully executed hosts
      set_fact:
        successful_hosts: "{{ successful_hosts|default([]) + [inventory_hostname] }}"

    - block:              
      - name: Check if previous roles succeeded
        assert:
          that:
            - "{{ host_failed is true }}"
        ignore_errors: true

      - name: Import multiple roles
        include_role:
          name: "{{ roles }}"
        loop:
          - roles/role_download_artifact
          - roles/role_create_config
          - roles/role_deploy_app
        loop_control:
              loop_var: roles
        when: not host_failed
        
      rescue:
        - name: "Host failed: {{ inventory_hostname }}"
          set_fact:
            host_failed: true
            successful_hosts: "{{ successful_hosts|default([]) + [inventory_hostname] }}"
          delegate_to: {{ inventory_hostname }}
          delegate_facts: true
  vars_files:
    - ../roles/default/vars.yml

- hosts: all
  serial: 1
  any_errors_fatal: true
  vars_files:
    - ../roles/default/vars.yml
  tasks:
    - name: run rollback
      include_role: 
        name: ../roles/role_rollback
      when: host_failed
ansible ansible-2.x rollback
1个回答
0
投票

我认为你目光短浅,处于反模式领域。虽然我讨厌回答一个没有被问到的问题,但我真的认为你应该退后一步,尝试考虑让你的戏剧/角色更加 Ansible 风格。

如果您希望在发生故障时执行清理角色,请不要尝试在控制器上发生一些魔法,角色应该只处理故障并调用清理角色。好的角色是幂等且独立的。

然后 Ansible 和 Tower 将使用其所有内置内容来干净利落地报告每个主机的状态和变化。

至于您似乎正在寻找的另一部分,一旦一台主机出现故障,您希望停止运行的其余部分,这位于元模块中。

有多种选项,end_host、end_play、end_serial。

从你的描述来看,我相信你想要 end_play。

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/meta_module.html

© www.soinside.com 2019 - 2024. All rights reserved.