allow you to declare tasks to be performed on remote hosts. Ansible playbooks Overview of Playbook Structure: specifies a group of tasks to be executed on a set of hosts. Play: an action to be performed on the host. Task: a piece of code for a specific task. Module: What are 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 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. ansible_facts 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 directive in a task triggers a handler if the task results in any changes to the host. notify Listen The directive allows multiple tasks to notify the same handler even if they use different names. listen notify Practice Exercises We'll start with two pre-configured inventory files. contains two hosts while contains one host. Inventory-webserver1.yaml inventory-webserver2.yaml Clone the repo 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 Spin up the environment using docker-compose docker compose up -d --build 4. SSH into the Ansible server ssh -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes root@localhost -p 2200 # password: test123 Working with Playbooks Create playbook file cd ansible_learn touch install_nginx.yaml nano install_nginx.yaml 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 Run the linter ansible-lint install_nginx.yaml 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 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 Task Controls & Handlers We want to create a playbook that installs Apache on servers that do not have a specific file (e.g., ), and then use a handler to restart Apache if it is newly installed or updated. /var/www/html/index.nginx-debian.html Create & open the file install_nginx.yaml touch conditional_install_apache.yaml nano conditional_install_apache.yaml Add a condition to install Apache if doesn't exist then add a handler to restart Apache if it is newly installed. /var/www/html/index.nginx-debian.html - 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. Run the linter ansible-lint conditional_install_apache.yaml 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 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 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. Also published here.