Hello everyone!! In this post I would like to experiment with the failure handling with block-rescue-always block in a Ansible tasks in playbook.
Prerequisites
* Ansible installed and their must be Target nodes
* Basic understanding of any programming language that uses try- catch blocks
Ansible stops playbook execution on a task failure and we can choose to ignore that using 'ignore_errors' to continue with remaining tasks. (in Python we have 'pass' similar to that).
If you have couple of tasks in a playbook, when first task fails Ansible stops there. But if you want to execute the next tasks even though your first task failed.
---
# File name: ignore_err.yml
- name: check ignore errors
hosts: localhost
gather_facts: false
tasks:
- block:
- command: "ls ~/"
- command: "ls ~/bin"
- command: "ls /etc/hosts"
become_user: root
become: yes
ignore_errors: yes
Now you can try to execute with 13 line and with out that line observe the output.
ansible-playbook ignore_err.yml
Execution of ignore_error play.
block concept
Common tasks
1. Install Apache httpd, memcached packages
2. We can use templates/src
3. We can start the services
tasks:
- block:
- yum: name={{ item }} state=installed
with_items:
- httpd
- memcached
- template: src=templates/src.j2 dest=/etc/mytest.conf
- service: name=httpd state=started enabled=True
when: ansible_distribution == 'CentOS'
become: true
become_user: root
Nested blocks
Block of blocks
---
- name: Block of blocks
tasks:
- name: install web server
- block:
- block:
- name: Install apache2
apt: name=apache2 state=present
when: ansible_os_family == "Debian"
- block:
- name: Install HTTPd
yum: name=httpd state=present
when: ansible_os_family == "RedHat"
tags: package
Block-level variable scope
We can have different scope for the variables defined at global playbook level and here we can also experiance the block level variables they can be only accessable with in the block, outside the block it will be 'UNDEFINED VARIABLE'.
- hosts: localhost
vars:
mystate: Happy
tasks:
- block:
- debug: var=mystate
- debug: var=mynextstate
vars:
mynextstate: Learning
- debug: var=mynextstate
Execution:
ansible-playbook block_vars.yml
Screenshot of execution:
block-rescue
Ansible allows us to define the scope for do the code has errors under the
block directive. When fatal error encountered Ansible control will jump out to the
rescue directive section. Where you can perform some tasks that can be like sending failure notifications to the team on slack or email or pager.
- name: Testing block-rescue directives
hosts: localhost
tasks:
- name: Handling the error tasks status
block:
- debug:
msg: 'This task is successful'
- name: This will force failure
command: /bin/false
- debug:
msg: 'This task will not be executed'
rescue:
- name: Sleep for 30 seconds and continue with play
wait_for:
timeout: 30
delegate_to: localhost
- debug:
msg: 'As there was a failure in block section, rescue section will run'
Execution
ansible-playbook block-rescue.yml
Screenshot:
block-rescue-always in Ansible
The error point can be by running /usr/bin/false command
Error handling with three blocks
1. block which contains tasks there could be some possible errors
2. rescue part will be executed when there is error occurred in the upper block
3. To ensure some task that should executed always even when you are using the block having errors or not.
---
- name: save file as block-rescue-always.yml
hosts: localhost
connection: local
tasks:
- block:
- debug:
msg: "I execute here..."
- command: /usr/bin/false
- debug:
msg: "I never touched :("
rescue:
- debug:
msg: "I caught Error here..."
- command: /usr/bin/false
- debug:
msg: "I also never touched..."
always:
- debug:
msg: "I am always there like God!"
Execution output
ansible-playbook block_rescue_always.yml
screenshot:
Using fail module in Ansible play
In most of the automation projects, Focus on the failure with handling tasks is major requirement
---
- name: testing fail
gather_facts: no
hosts: localhost
tasks:
- name: check home bin folder
command: ls ~/bin
register: error_msg
ignore_errors: yes
- name: debug bin
debug:
msg: "{{ error_msg }}"
- name: failing blok
fail:
msg: "FAILED exiting now..."
when: error_msg.rc != 0
- name: check home bin folder
command: ls ~/
register: home_msg
- name: debug home
debug:
msg: "{{ error_msg }}"
Execution of the fail module
ansible-playbook fail_test.yml
Screenshot:
|
Ansible fail module error handling ignore error |
Hope you like this post write your experience with error handling in Ansible playbooks.
References: