DEV Community

Cover image for Ansible 101: Playbooks, Task Controls & Handlers
Javel Rowe
Javel Rowe

Posted on • Updated on • Originally published at javel.dev

Ansible 101: Playbooks, Task Controls & Handlers

What is a Playbook?

Ansible playbooks allow you to declare tasks to be performed on remote hosts.

Overview of Playbook Structure:

Playbook analogy. A pic of a cookbook represents the playbook, Each recipe in the cookbook is a play and the steps in the recipe are tasks. Modules are represented by an image of cooking utensils and ingredients.

  1. Play: specifies a group of tasks to be executed on a set of hosts.

  2. Task: an action to be performed on the host.

  3. Module: a piece of code for a specific task.

What is Task Control & Handler?

These are methods of controlling how and when your automation scripts are executed. Task control lets you specify conditions for running tasks while handlers are a form of tasks that you trigger only when changes need to be applied.

Task Control Overview

Task control in Ansible allows you to state the conditions under which your scripts should run. This can be implemented using conditionals such as:

When

This conditional allows you to execute a task only if it evaluates to true.

Ansible Facts

ansible_facts are variables containing information like network interfaces, operating system, IP addresses, and more, which are gathered from host machines and can be used in conditionals.

Task Handlers Overview

Handlers are tasks set to run only when certain changes occur, such as when a service's configuration file is updated by another task.

Notify

The notify directive in a task triggers a handler if the task results in any changes to the host.

Listen

The listen  directive allows multiple tasks to notify the same handler even if they use different notify names.

Practice

We'll start with two pre-configured inventory files. Inventory-webserver1.yaml contains two hosts while inventory-webserver2.yaml contains one host.

  1. Clone the repo
git clone https://github.com/perplexedyawdie/ansible-learn.git
Enter fullscreen mode Exit fullscreen mode

2. Spin up the environment using docker-compose

docker compose up -d --build
Enter fullscreen mode Exit fullscreen mode

3. SSH into the Ansible server

ssh -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes root@localhost -p 2200# password: test123
Enter fullscreen mode Exit fullscreen mode

4. Change directory to ansible_learn

cd ansible_learn
Enter fullscreen mode Exit fullscreen mode

Working with Playbooks

5. Create playbook file


touch install_nginx.yaml

nano install_nginx.yaml

Enter fullscreen mode Exit fullscreen mode

6. Add the following config to install nginx

# ansible_learn/install_nginx.yaml
# setting the state param to "present" will ensure that it is installed

- name: Install NGINX Web Server
  hosts: webserver1
  tasks:
    - name: Install NGINX
      ansible.builtin.apt:
        name: nginx
        state: present
Enter fullscreen mode Exit fullscreen mode

7. Run the linter

ansible-lint install_nginx.yaml

Enter fullscreen mode Exit fullscreen mode

8. Execute the playbook on inventory-webserver1.yaml

ansible-playbook --key-file /root/.ssh/id_rsa_ansible -u root -i inventory-webserver1.yaml install_nginx.yaml

Enter fullscreen mode Exit fullscreen mode

9. Confirm installation on server1 & server2 then check if it's installed on server3


ssh -i /root/.ssh/id_rsa_ansible root@server1 nginx -V
ssh -i /root/.ssh/id_rsa_ansible root@server2 nginx -V


ssh -i /root/.ssh/id_rsa_ansible root@server3 nginx -V
Enter fullscreen mode Exit fullscreen mode

Task Controls & Handlers

We want to create a playbook that installs Apache on servers that do not have a specific file (e.g., /var/www/html/index.nginx-debian.html), and then use a handler to restart Apache if it is newly installed or updated.

10. Create & open the install_nginx.yaml file

touch conditional_install_apache.yaml

nano conditional_install_apache.yaml
Enter fullscreen mode Exit fullscreen mode

11. Add condition to install Apache if /var/www/html/index.nginx-debian.html doesn't exist then add a handler to restart Apache if it is newly installed.


- name: Conditional Install and Restart Apache
  hosts: all
  tasks:
    - name: Check if NGINX Default Page Exists
      ansible.builtin.stat:
        path: /var/www/html/index.nginx-debian.html
      register: nginx_page

    - name: Install Apache
      ansible.builtin.apt:
        name: apache2
        state: present
      when: not nginx_page.stat.exists
      notify: Restart Apache

  handlers:
    - name: Restart Apache
      listen: "Restart Apache"
      ansible.builtin.service:
        name: apache2
        state: restarted

# The stat module checks for the existence of the default NGINX page. The result is registered in nginx_page.
# The installation task uses the when condition to install Apache only if the file does not exist.
# If the installation task runs, it notifies the handler to restart Apache.
# The handler listens for the notification and uses the service module to restart Apache.
Enter fullscreen mode Exit fullscreen mode

12. Run the linter

ansible-lint conditional_install_apache.yaml

Enter fullscreen mode Exit fullscreen mode

13. Execute the playbook on inventory-webserver1.yaml & inventory-webserver2.yaml

# webserver1
ansible-playbook --key-file /root/.ssh/id_rsa_ansible -u root -i inventory-webserver1.yaml conditional_install_apache.yaml

#webserver2
ansible-playbook --key-file /root/.ssh/id_rsa_ansible -u root -i inventory-webserver2.yaml conditional_install_apache.yaml
Enter fullscreen mode Exit fullscreen mode

14. Confirm installation on server3 then check if it's installed on server1 & server2


ssh -i /root/.ssh/id_rsa_ansible root@server1 apache2 -V
ssh -i /root/.ssh/id_rsa_ansible root@server2 apache2 -V


ssh -i /root/.ssh/id_rsa_ansible root@server3 apache2 -V
Enter fullscreen mode Exit fullscreen mode

Recap

Awesome effort! We just learned how to define Ansible playbooks and how to control the flow of execution using conditionals. Next, we'll look on variables, gathering facts about host machines and how to manage config files using templates.

Top comments (0)