Using special variables in blocks to improve code readability
This post will cover using special variables that Ansible provides when using blocks for error handling.
I know that it has been a while since i’ve posted. I took a lovely vacation to Japan for 3 weeks and the pre and post trip logistics have me a bit bogged down. This will be a short one.
I just recently discovered that when using a block (and rescue) that two special variables are created that are very useful in limiting the amount of YAML that needs to be written.
In the example below we’re installing a couple yum packages and applying a config file.
tasks:
- name: Install, configure, and start Apache
when: ansible_facts['distribution'] == 'CentOS'
block:
- name: Install httpd and memcached
ansible.builtin.yum:
name:
- httpd
- memcached
state: present
- name: Apply the foo config template
ansible.builtin.template:
src: templates/src.j2
dest: /etc/foo.conf
- name: Start service bar and enable it
ansible.builtin.service:
name: bar
state: started
enabled: True
When developing this play, we have to assume that it will fail at some point. We’ll obviously want to me notified of this. We’ll use a rescue section to accomplish this.
tasks:
- name: Install, configure, and start Apache
when: ansible_facts['distribution'] == 'CentOS'
block:
- name: Install httpd and memcached
ansible.builtin.yum:
name:
- httpd
- memcached
state: present
register: install_result
---Truncated---
rescue:
- name: Send alert message
when: install_result is failed
ansible.custom.slack:
msg: "Something went wrong with the installation of Apache"
- name: Send alert message
when: config_result is failed
ansible.custom.slack:
msg: "Something went wrong with the configuration of Apache"
- name: Send alert message
when: service_result is failed
ansible.custom.slack:
msg: "Something went wrong with the starting of Apache"
When I was beginning with Ansible it made sense to use rescue in this fashion. It’s more like Python where you catch specific exceptions. However, Ansible provides two special variables to simplify things.
ansible_failed_task and ansible_failed_result allows the rescue section to be much simpler by saving the information from the task that failed. This allows you to catch the error very simply as shown below.
---Truncated---
rescue:
- name: Send alert message
ansible.custom.slack:
msg: "An error occurred during {{ ansible_failed_task }}. Error output: {{ ansible_failed_result }}"
This can be extremely beneficial in a complex playbook or block by reducing the size of the rescue by quite a bit in some cases. It won’t help in every case however.
Thanks for reading! I’ll hopefully be back to posting more regularly and I should have some AAP 2.4 > 2.5 content soon as my work transitions. I will likely have some Event-Driven Ansible content as well!
Cheers!