Ansible playbooks allow you to declare tasks to be performed on remote hosts.
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 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.
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.
We'll start with two pre-configured inventory files. Inventory-webserver1.yaml
contains two hosts while inventory-webserver2.yaml
contains one host.
git clone https://github.com/perplexedyawdie/ansible-learn.git
2. Change the directory to playbooks-task-control-handlers
cd ansible-learn/playbooks-task-control-handlers
docker compose up -d --build
4. SSH into the Ansible server
ssh -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes root@localhost -p 2200
# password: test123
cd ansible_learn
touch install_nginx.yaml
nano install_nginx.yaml
# 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
ansible-lint install_nginx.yaml
inventory-webserver1.yaml
ansible-playbook --key-file /root/.ssh/id_rsa_ansible -u root -i inventory-webserver1.yaml install_nginx.yaml
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
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.
install_nginx.yaml
filetouch conditional_install_apache.yaml
nano conditional_install_apache.yaml
/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.
ansible-lint conditional_install_apache.yaml
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
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
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.
Also published here.