Overview
When playbooks grow in size, they become challenging to manage. Modularization helps by separating logic from data, making playbooks cleaner and more maintainable. As you introduce these abstractions, it's crucial to integrate robust error handling and debugging techniques to ensure reliability.
Roles
Roles in Ansible are units of organization that allow you to group related tasks, variables, files, and templates. They make your playbooks modular. Here’s how to create and use them:
Creating a Role: Organize your playbook into a directory structure with separate files for tasks, handlers, defaults, vars, files, and templates.
Using Roles: Incorporate a role into your playbook with the
roles
property or theinclude_role
module for dynamic inclusion.
- hosts: all
roles:
- role: my_custom_role
Error Handling & Debugging
Error Handling
Ansible provides ways to define custom failure conditions and manage the playbook execution flow when encountering errors.
-
Block and Rescue: Use
block
to group tasks andrescue
to define remediation steps if any task in the block fails.
tasks:
- block:
- name: Attempt to do something
command: /bin/false
rescue:
- name: This will run on failure
command: /bin/true
Debugger
Ansible’s debugger lets you interactively troubleshoot tasks that fail during playbook execution. It can be invoked by adding debugger
to your playbook. Use one of the following values to control when the debugger is activated:
always
: always activate debuggernever
: never activate debuggeron_failed
: activate only on task failureon_unreachable
: activate when a host is unreachableon_skipped
: activate when a task is skipped
- name: Install NGINX Web Server
hosts: webservers
tasks:
- name: Install NGINX
ansible.builtin.apt:
name: httpd
state: present
debugger: on_failed
Core commands when working with the debugger include:
print
: display task detailstask.args['arg-name'] = 'updated-val'
: update arg valueredo
: rerun the taskquit
: exit the debugger
Practice
Our aim is to modularize the process of installing NGINX and updating the homepage. We also want to handle an error caused by incorrect package name and dynamically fix it.
- Clone the repo
git clone https://github.com/perplexedyawdie/ansible-learn.git
2. Spin up the environment using docker-compose
docker compose up -d --build
3. SSH into the Ansible server
ssh -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes root@localhost -p 2200# password: test123
4. Change directory to ansible_learn
cd ansible_learn
Roles & Modularization
5. Create the roles directory with the relevant folders. For this task, we'll only require tasks
, templates
and handlers
cd ansible_learn
mkdir -p roles/nginx/tasks roles/nginx/templates roles/nginx/handlers
6. Create the template that will generate the homepage.
Filename: index.html.j2
Location: ansible_learn/roles/nginx/templates
<html>
<head>
<title>Welcome to {{ ansible_facts['os_family'] }}</title>
</head>
<body>
<h1>Server running on {{ ansible_facts['distribution'] }}</h1>
</body>
</html>
7. Create the tasks that will install NGINX, generate the homepage, and copy it to the server.
Filename:
main.yaml
Location:
ansible_learn/roles/nginx/tasks
- name: Install NGINX for Debian-based systems
ansible.builtin.apt:
name: nginx
state: present
- name: Create Homepage with Jinja2 Template for NGINX
ansible.builtin.template:
src: index.html.j2
dest: /var/www/html/index.html
mode: '644'
notify: restart nginx
8. Create the handler that will restart NGINX upon update.
Filename:
main.yaml
Location:
ansible_learn/roles/nginx/handlers
- name: Restart NGINX
listen: "restart nginx"
ansible.builtin.service:
name: nginx
state: restarted
9. Create the playbook.
Filename:
nginx_setup.yaml
Location:
ansible_learn
- name: Install NGINX
hosts: all
roles:
- role: nginx
10. Run the linter
ansible-lint nginx_setup.yaml
11. Execute the playbook.
ansible-playbook --key-file /root/.ssh/id_rsa_ansible -u root -i inventory.yaml nginx_setup.yaml
12. Confirm deployment by visiting http://localhost:2203 in your browser.
Error Handling
The aim is to use block
and rescue
to print a custom message on error.
13. Create a new playbook that should install Apache but use the wrong package name then add block & rescue properties.Filename: error_test.yaml
Location: ansible_learn
- name: Install Apache on Ubuntu
hosts: all
tasks:
- name: Install Apache for Debian-based systems
block:
- name: Installer
ansible.builtin.apt:
name: httpd
state: present
rescue:
- name: Installer errors
ansible.builtin.debug:
msg: "Error installing Apache on {{ ansible_facts['distribution'] }}"
14. Run the linter
ansible-lint error_test.yaml
15. Execute the playbook
ansible-playbook --key-file /root/.ssh/id_rsa_ansible -u root -i inventory.yaml error_test.yaml
Debugging
The aim is to use the debugger
and dynamically fix an error in a task.
16. Update the error_test.yaml
playbook and add the debugger
property
- name: Install Apache on Ubuntu
hosts: all
debugger: on_failed
tasks:
- name: Install Apache for Debian-based systems
block:
- name: Installer
ansible.builtin.apt:
name: httpd
state: present
rescue:
- name: Installer errors
ansible.builtin.debug:
msg: "Error installing Apache on {{ ansible_facts['distribution'] }}"
17. Run the linter
ansible-lint error_test.yaml
18. Execute the playbook
ansible-playbook --key-file /root/.ssh/id_rsa_ansible -u root -i inventory.yaml error_test.yaml
19. In the interactive debugger, run the following commands to update the package name
# display all args in the failed task, we are interested in the name, since that contains the name of the package
p task.args
# update the package name. When installing Apache on Ubuntu, we use apache2
task.args['name'] = 'apache2'
# rerun the task
redo
# exit the debugger
quit
20. Confirm successful installation of Apache
ssh -i /root/.ssh/id_rsa_ansible root@server1 apache2 -V
Recap
Great effort! We learned how to create playbooks that are easier to extend and maintain along with how to handle errors and debug tasks to ensure reliability. For the final tutorial, we'll look at how to safely store sensitive data using Ansible Vault. Til then, take care! 👋
Top comments (0)