Ansible剧本角色与任务执行异常处理方案咨询
Alright, let's tackle this Ansible problem step by step. Your requirement is straightforward but needs careful handling of error flow—here's how you can implement it cleanly:
Core Approach
We'll split your playbook into two distinct plays to separate role execution from the mandatory post-task:
- The first play runs all your roles, configured to halt immediately if any task fails (skipping all remaining roles).
- The second play runs your specific task on
system_aregardless of whether the first play succeeded or failed.
Playbook Implementation
Here's the full playbook code with clear explanations:
# Play 1: Execute all roles, halt on any failure - name: Run designated roles on system_a and system_b hosts: system_a, system_b # Critical setting: If ANY task fails on ANY host, stop the entire play immediately # This skips all leftover roles (for both system_a and system_b) any_errors_fatal: yes tasks: # Roles restricted to system_a - name: Execute role1 on system_a hosts import_role: name: role1 when: inventory_hostname in groups['system_a'] - name: Execute role2 on system_a hosts import_role: name: role2 when: inventory_hostname in groups['system_a'] # Roles restricted to system_b - name: Execute role3 on system_b hosts import_role: name: role3 when: inventory_hostname in groups['system_b'] - name: Execute role4 on system_b hosts import_role: name: role4 when: inventory_hostname in groups['system_b'] - name: Execute role5 on system_b hosts import_role: name: role5 when: inventory_hostname in groups['system_b'] - name: Execute role6 on system_b hosts import_role: name: role6 when: inventory_hostname in groups['system_b'] # Play 2: Mandatory task for system_a (runs no matter what) - name: Run required specific task on system_a hosts: system_a tasks: - name: Your specific task here # Replace this with your actual task (e.g., log cleanup, service restart, alert) debug: msg: "Executing the mandatory post-task on system_a"
Key Details Breakdown
any_errors_fatal: yes: This is the linchpin of the solution. It ensures that if any task in the first play fails (on any host), Ansible stops executing all remaining tasks/roles immediately—exactly what you need to skip leftover roles when something goes wrong.- Host targeting with
when: Each role is locked to its intended host group, so roles only run on the correct machines and don't waste cycles on unrelated hosts. - Separate play for the specific task: By isolating this task in its own play, it will always execute after the first play finishes—whether the first play succeeded fully or failed halfway through. This guarantees your system_a task runs no matter the outcome of role execution.
Alternative: Single-Play with Block/Rescue
If you prefer to keep all logic in one play, you can use Ansible's block/rescue structure. This works similarly but keeps everything contained:
- name: Handle roles and post-task in a single play hosts: system_a, system_b tasks: - block: # All role executions go here - import_role: name=role1 when: inventory_hostname in groups['system_a'] - import_role: name=role2 when: inventory_hostname in groups['system_a'] - import_role: name=role3 when: inventory_hostname in groups['system_b'] - import_role: name=role4 when: inventory_hostname in groups['system_b'] - import_role: name=role5 when: inventory_hostname in groups['system_b'] - import_role: name=role6 when: inventory_hostname in groups['system_b'] rescue: # Optional: Mark play failure for logging/alerting purposes - name: Flag play as failed set_fact: play_failed: true delegate_to: localhost run_once: true # Mandatory task for system_a (runs regardless of block success/failure) - name: Execute specific task on system_a debug: msg: "Running the required task on system_a" when: inventory_hostname in groups['system_a']
Either approach will meet your requirements—pick the one that fits your existing playbook structure best!
内容的提问来源于stack exchange,提问作者Ankur Gupta
相关产品推荐
相关产品推荐

