What are blocks in Ansible and how do you handle errors?
Learn how Ansible blocks group tasks and handle errors with block, rescue and always sections plus ignore_errors, with examples and interview tips.
Expected Interview Answer
A block in Ansible groups a set of tasks together so they can share directives and be treated as a unit, and it enables structured error handling through the block, rescue, and always sections — the Ansible equivalent of try/catch/finally.
Tasks in the block run normally; if any task fails, execution jumps to the rescue section where you can recover, notify, or clean up; the always section runs no matter what, succeed or fail. Blocks can also apply shared directives like when, become, tags, and ignore_errors to every task inside them at once. Beyond blocks, Ansible offers task-level error controls such as ignore_errors, failed_when, changed_when, and any_errors_fatal to fine-tune what counts as a failure.
- Structured try/rescue/always error handling like a programming language
- Apply shared directives to many tasks with one declaration
- Graceful recovery and guaranteed cleanup steps
- Cleaner, more readable playbooks
- Combine with failed_when and ignore_errors for precise failure control
AI Mentor Explanation
A block is like an over bowled by one bowler: the six deliveries belong together as a unit. If a delivery goes wrong and a wicket-style crisis erupts (rescue), the fielding captain runs a recovery plan, and no matter the outcome the umpire always signals the over complete and updates the scorebook. Grouping the balls lets one field-setting apply to the whole over instead of ball by ball.
Step-by-Step Explanation
Step 1
Group tasks in a block
Put related tasks under a 'block:' key so they share directives and act as one unit.
Step 2
Add a rescue section
Under 'rescue:', list tasks that run only if any task in the block fails — for recovery, alerts, or rollback.
Step 3
Add an always section
Under 'always:', list tasks that run unconditionally after block/rescue — ideal for cleanup like removing temp files.
Step 4
Apply shared directives
Attach when, become, tags, or ignore_errors at the block level so they apply to every contained task.
Step 5
Tune failure conditions
Use failed_when, changed_when, and ignore_errors on individual tasks to control exactly what counts as failure.
What Interviewer Expects
- Understanding that block/rescue/always mirrors try/catch/finally
- Knowing rescue only runs when a block task fails
- Knowing always runs regardless of success or failure
- Awareness that blocks apply shared directives to grouped tasks
- Familiarity with ignore_errors, failed_when and changed_when
Common Mistakes
- Thinking always runs only on failure (it runs every time)
- Assuming rescue runs even when the block succeeds
- Confusing ignore_errors with rescue-based recovery
- Forgetting that a failure in rescue itself is not caught again
- Believing blocks can loop with loop directives (they cannot)
Best Answer (HR Friendly)
“Blocks let you group related automation steps and handle errors gracefully — a bit like a safety net. If something goes wrong, a rescue section runs recovery steps, and an always section runs cleanup no matter what, so the process stays reliable.”
Code Example
- name: Deploy application safely
hosts: web
become: true
tasks:
- name: Deploy and verify
block:
- name: Pull new release
ansible.builtin.git:
repo: https://example.com/app.git
dest: /opt/app
- name: Restart service
ansible.builtin.service:
name: app
state: restarted
rescue:
- name: Roll back on failure
ansible.builtin.command: /opt/app/rollback.sh
- name: Notify team
ansible.builtin.debug:
msg: "Deploy failed, rolled back"
always:
- name: Clean temp files
ansible.builtin.file:
path: /tmp/deploy.lock
state: absentFollow-up Questions
- What is the difference between ignore_errors and a rescue block?
- Does the always section run if a task in rescue fails?
- How do failed_when and changed_when change task outcomes?
- Can you use loops directly on a block?
- What does any_errors_fatal do across multiple hosts?
MCQ Practice
1. When does the 'rescue' section of an Ansible block execute?
Rescue runs only if one of the tasks inside the block fails, similar to a catch clause.
2. When does the 'always' section run?
The always section runs unconditionally after the block and any rescue, like a finally clause.
3. Which directive tells Ansible a task should not be treated as failed on non-zero exit?
ignore_errors: true lets the play continue even if the task fails, without triggering rescue.
Flash Cards
What three sections make up block-based error handling? — block (main tasks), rescue (runs on failure), and always (runs every time).
Block/rescue/always is analogous to what programming construct? — try / catch / finally.
What does ignore_errors: true do? — Marks a failing task as non-fatal so the play continues; it does not trigger a rescue block.
What does failed_when do? — Defines a custom condition under which a task is considered failed, overriding the default exit-code check.