Updated April 13, 2023
Introduction to Ansible Block
In Ansible, we have plenty of such features which can make your job easy. One such feature is block, which enables you to run a set of tasks by grouping them and provides functionalities that you can leverage for error handling. Almost all the things which can do with a task, are doable with block, that gives you easiness to not write the code to set any data or any directives to different task section. For error handling, it gives features like rescue and always, which are very useful in the successful run of a playbook. In this article, we will learn about the Ansible block by going into details of it and with examples.
What is Ansible Block?
Ansible block is a feature that makes the grouping of tasks possible, which can be treated in the same way as a task is treated by the Ansible system. That means like the way we can set data or derivatives or any other feature parameter for a task, in a similar way we can do with Ansible block. Adding to this, we have parameters that are making error handling possible. Below are the keywords which are used in Ansible blocks: –
- Block: Under this parameter, we define the tasks and other task-related parameters. All the tasks under a block are treated as a group and accordingly, we can set feature parameters on this
- Rescue: Under this parameter, we define all such tasks which need to be executed whenever the block section fails. This makes the playbook to continue to run and not halt at the failure of a But make note that, bad syntax or unreachable host are not rescuable.
- Always: Under this parameter, we defined all those tasks which will run despite the success or failure of the block.
How Does Ansible Block Work?
To make Ansible block run successfully, we need to pay more attention to syntax and indentation, as a feature parameter will be realized according to its indentation in the playbook. All the conditionals, become, etc. related parameters defined at the task level will run at that level and all parameters defined on block level will be realized on all tasks grouped by block. Precedence will be given to task level if defined at both task and block level.
Syntax:
tasks:
- name: Few tasks will be executed block:
- name: Task 1
shell: <command to execute>
- name: Task 2
command: <commans to execute >
when: ansible_facts['distribution'] == 'RedHat' become_user: root
become: true
For error handling, we have a rescue section, which will be invoked when the block section has failed status. If the block section is successful, then the rescue section will not be invoked.
The syntax will be like below: –
tasks:
- name: Handling the error/failue status block:
- debug:
msg: 'This task is successful'
- name: This will force failue command: /bin/false
- debug:
msg: 'This task will not be executed' rescue:
- debug:
msg: 'As there was a failure in block section, rescue section will run'
When we have a task or set of tasks that need to be run anyway despite the status of the block section. We can use always, which have syntax like below: –
tasks:
- name: Handling the error/failue status block:
- debug:
msg: 'This task is successful'
- name: This will force failue command: /bin/false
- debug:
msg: 'This task will not be executed' always:
- debug:
msg: 'I will run always'
In recent versions of Ansible, we got a few variables introduced, which were helpful while dealing with failure in block section: –
- ansible_failed_task: This is to get the task which got failed and triggered.
- ansible_failed_result: This captures the failure results of a failed.
In this section, we will learn by doing looking at some examples where we tried to test the functionality of Ansible Block. Also, we shall know about the lab environment before moving ahead in this section.
Here we have one Ansible controller node named ansible-controller. As target nodes, we have two remote machines. The first machine is a Red Hat Enterprise Linux machine named as host-one and the second machine is an Ubuntu machine named as host-two. We will run our playbooks on the Ansible controller machine and make changes on remote target machines.
Examples of Using Block in Ansible
Below are the examples of Ansible Block:
Example #1
In this example, we will create a block to install and start httpd service on a remote host named host-one. For this, we will create a playbook with the below contents and will run as not-admin ec2- user. Then we will use become a method to run the command as the root users. Also, we have used a conditional which will check whether the Linux distribution is RedHat, then only it will run.
Code:
---
- hosts: host-one tasks:
- name: Install and Start HTTPD block:
- name: Install HTTPD yum:
name: httpd state: installed
- name: Start HTTPD service and enable service:
name: httpd state: started enabled: True
when: ansible_facts['distribution'] == 'RedHat' ignore_errors: yes
become_user: root become: true
Running this playbook like below will give the output where you can see that httpd service is installed first on host-one and then its started on this host. The service starting needs privileges on a server, so this is done by sudo method by becoming user root.
ansible-playbook ansible_block.yaml -v
Output:
Example #2
In this example, we see error handling functionality of the Ansible block, rescue, and always. We have a playbook like below:
Code:
---
- hosts: all tasks:
- name: Here we are starting a service. block:
- debug:
msg: "This section is in Block section, where we are starting service which will fail as package not installed"
- name: start the httpd service service:
name: httpd state: started
when: ansible_distribution == "RedHat" rescue:
- debug:
msg: "This section is in rescue section, which means block section failed, so we install httpd/apache"
- name: here we install httpd on RedHat distribution yum:
name: httpd
state: installed
- name: start the httpd service service:
name: httpd state: started
when: ansible_distribution == "RedHat" always:
- debug:
msg: "This section is in always section and will do changes in httpd.conf file"
- lineinfile:
path: /etc/httpd/conf/httpd.conf regexp: '^Listen '
insertafter: '^#Listen ' line: Listen 8080
when: ansible_distribution == "RedHat"
Now running this playbook will give below output where we can see that when condition met to check Linux distribution equals to RedHat. Ansible try to start the service on remote hosts, but it failed as httpd package is not installed on the remote host. So error occurred and rescue section is invoked, where the package is installed and service is started, then in the always section, changes in httpd.conf is made.
ansible-playbook ansible_block_rescue_always.yaml
Output:
Conclusion
As we saw in this article, Ansible Block can be an import part of your Ansible skills, which you must possess to work efficiently, especially in production environments, where error handling and running successfully is the topmost priority. So learn it first and then use it to the full extent.
Recommended Article
This is a guide to Ansible Block. Here we discuss What is Ansible Block and its syntax along with examples as well as code implementation. You can also go through our other suggested articles to learn more –