Ansible

Ansible Block and Rescue

Ansible is an open-source automation tool that allows us to manage configurations, deploy applications, and perform task automation using the declarative language in TAML to define the tasks and the order of execution.

Every task in Ansible tells the target system what state it should be in rather than just giving commands to get it there. This distinction makes Ansible’s approach idempotent which means running the same task multiple times won’t have different results.

However, real-world scenarios sometimes lead to unexpected issues. A task might fail due to an unforeseen condition or a temporary issue.

This is where Ansible block and rescue directives come into play. They provide a structured way to anticipate and handle the errors that may occur gracefully.

The essence of this tutorial is to discuss and learn about the Ansible block and rescue features to group and handle the errors in Ansible playbooks.

What Is an Ansible Block?

In Ansible, a block is a grouping of tasks that is executed as a unit. You can think of it as bundling multiple tasks together so they are treated as one logical unit.

There are three main advantages of Ansible blocks:

  • Group tasks logically
  • Apply the same attributes (like become or tags) to multiple tasks
  • Handle the errors for a group of tasks using the “rescue” and “always” sections

Define an Ansible Block

We can define an Ansible block by using the “block” keyword. Inside the block, we can define any number of tasks, each with individual properties and requirements.

The following playbook demonstrates how we can use the Ansible block feature to group the tasks together:

- name: Ensure webserver is configured
hosts: webservers
tasks:
- block:
- name: Install apache
apt:
name: apache2
state: present

- name: Start apache service
service:
name: apache2
state: started

In this case, we use an Ansible block to install and start the Apache server as a single unit.

Using Ansible Blocks and Rescue

The power of blocks becomes apparent when we combine it with the “rescue” and “always” clauses.

These allow us to specify the tasks that should run if there’s an error within the block and the tasks that should run regardless of success or failure.

We can express the syntax of these blocks as demonstrated in the following:

Here’s a breakdown:

  1. Block – The block contains the main tasks that we wish to execute.
  2. Rescue – Inside the rescue block, we define the tasks that will be performed if any of the tasks within the block fails.
  3. Always – Finally, we have the “always” block. This defines a set of tasks that should run after the block and rescue options, irrespective of their outcomes.

To better illustrate how these blocks work, take the previous example that installs and starts the Apache service.

- name: Ensure webserver is configured
hosts: webservers
tasks:
- block:
- name: Install apache
apt:
name: apache2
state: present
- name: Start apache service
service:
name: apache2
state: started
rescue:
- name: Send failure notification
mail:
to: admin@example.com
subject: "Apache setup failed!"
body: "Error setting up Apache on {{ ansible_hostname }}."
always:
- name: Write log for playbook run
local_action:
module: copy
content: "Playbook run at {{ ansible_date_time.iso8601 }}"
dest: "/var/log/ansible_run.log"

The previous example playbook introduces the basic error handling when installing and starting the Apache server. If either the installation or service start fails, we send an email notification to the admin with the error message.

Similarly, we also write the log of the playbook to a file, whether we encountered an error or not, as defined by the “always” section.

Conclusion

You now learned how to configure and set up the error-handling techniques in your Ansible playbooks by leveraging the power of block, rescue, and always directives. Using these features, you can tackle the unexpected with grace.

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list