Ansible Strategies
- Ansible strategy defines how a playbook is executed in ansible.
---
# sample ansible playbook (strategies)
- name: Deploy a web application
hosts: server1
tasks:
- name: Install dependencies
#-----<Some Code>-----
- name: Install MySQL Database
#-----<Some Code>-----
- name: Start MySQL Database
#-----<Some Code>-----
- name: Install Python Flask dependencies
#-----<Some Code>-----
- name: Run Web server
#-----<Some Code>-----
- With this playbook, imagine we are trying to install a web application on a single server in an all-in-one mode (meaning we have a database and web server running on the same system). It is pretty straightforward in a single server.
Linear Strategy
- By default, plays run with a linear strategy in which all hosts will run each task before any host starts the next task.
---
# sample ansible playbook (linear strategies)
- name: Deploy a web application
hosts: server1, server2, server3
tasks:
- name: Install dependencies
#-----<Some Code>-----
- name: Install MySQL Database
#-----<Some Code>-----
- name: Start MySQL Database
#-----<Some Code>-----
- name: Install Python Flask dependencies
#-----<Some Code>-----
- name: Run Web server
#-----<Some Code>-----
free strategy
- In this case, each server runs all of its tasks independently of other servers and does not wait for the task to finish on the other server. So each server can go right to the end as fast as it can and a host that is slower on a specific task won't hold up the rest of the host and tasks.
---
# sample ansible playbook (free strategies)
- name: Deploy a web application
hosts: server1, server2, server3
tasks:
- name: Install dependencies
#-----<Some Code>-----
- name: Install MySQL Database
#-----<Some Code>-----
- name: Start MySQL Database
#-----<Some Code>-----
- name: Install Python Flask dependencies
#-----<Some Code>-----
- name: Run Web server
#-----<Some Code>-----
Batch strategy
Imagine we have 5 servers but we want ansible to execute 3 servers at a time. This is where batch processing helps us. This is not a separate strategy this is based on a linear strategy but we can control the number of servers executed at a time in a batch
We have to specify a new option called serial where we can specify the number of servers we would like to process together.
---
# sample ansible playbook (batch strategies)
- name: Deploy a web application
hosts: server1, server2, server3
tasks:
- name: Install dependencies
#-----<Some Code>-----
- name: Install MySQL Database
#-----<Some Code>-----
- name: Start MySQL Database
#-----<Some Code>-----
- name: Install Python Flask dependencies
#-----<Some Code>-----
- name: Run Web server
#-----<Some Code>-----
Forks
Fork define how many server ansible can talk to at a time. Imagine in the previous example what if we had 1000 servers and wished to run our playbooks across all of them at the same time? Would ansible run the playbook on all of them at the same time?
The answer is no (unless you specify explicitly). Ansible uses parallel processes or forks to communicate with remote hosts. The default value is 5 and it is defined in the ansible configuration file ansible.cfg
grep fork /etc/ansible/ansible.cfg
forks = 5
So we try to run our playbook on 1000 hosts, and ansible will only run across 5 at a time. We can increase this value in the configuration file.
Error handling in Ansible
In Ansible it is a common thing to run the same playbook in parallel on many targets. Sometimes on a particular target, we receive an error. In this case, by default Ansible stops the execution on that target, but continues to run the playbook on the other targets. This is the ansible default behavior.
However, we can change the ansible default behavior by adding the any_errors_fatal: true line in the playbook (adding the line before the tasks section).
After adding any_errors_fata: true, if an error occurs Ansible stops the execution of the playbook on all the target
We can handle the errors at the task level as well like a playbook.
---
- hosts: all
become: yes
tasks:
- name: Install apache
apt:
name: apache2
state: latest
ignore_error: yes
register: results
- name: Install httpd
yum:
name: httpd
state: latest
failed_when: "'FAILED' in results"
ignore_error: yes - any error you can have at this task is ignored
failed_when: " 'FAILED' in results" - Ansible considers that this task failed if in the result of the task you find the word 'FAILED'
I hope you enjoyed this article, if you have any questions, comments, or feedback or if I made a mistake feel free to comment down below.