我需要在“all”定义的多个服务器上运行一组角色。我不知道服务的名称,因为它们源自 Ansible 塔的动态库存。
如果这些角色中的任何任务失败,我需要在已执行戏剧的所有主机上进行回滚(无论成功与否)。
例如,如果有host1、host2和host3,我在这些主机上执行我的角色。 Host1所有角色都通过。 Host2 一项任务失败,主机被标记为“失败”。主机3也执行失败。
我创作了两部剧:
首先执行角色,记录失败的主机,并且理想情况下希望在其中一个角色失败时停止在其余主机上的播放。这似乎不会发生。
我想在不使用 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 和 Tower 将使用其所有内置内容来干净利落地报告每个主机的状态和变化。
至于您似乎正在寻找的另一部分,一旦一台主机出现故障,您希望停止运行的其余部分,这位于元模块中。
有多种选项,end_host、end_play、end_serial。
从你的描述来看,我相信你想要 end_play。
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/meta_module.html