Conditional statements allow you to control the task execution based on specific conditions, ensuring that your playbooks respond appropriately to varying scenarios. Loops are control structures that allow you to repeat tasks across multiple items, such as iterating through a list of packages or files.
Conditional statements
In Ansible, conditional statement allow you to make decisions and execute different tasks based on specific conditions. Whether you want to configure services, install packages, or skip certain steps, conditionals play a crucial role.
Basic conditionals using the when
clause
The when
clause is the go-to tool for conditional execution. As a beginner you will mostly use Ansible Facts as input for conditional statements.
Facts are attributes of individual hosts, such as IP addresses, operating systems, and filesystem statuses. You can use conditionals based on facts to:
- Install specific packages based on OS versions.
- Skip tasks for specific operating systems.
- Perform tasks based on architecture.
To read the facts on a system you can use the ansible
command with the setup
module, but be notified about the facts you see this way will get an ansible_
addition prepending them like ansible_distribution_major_version
. You have to remove the ansible_
from them if you use it like distribution_major_version
.
ansible -i inventory -m ansible.builtin.setup all
You can read facts with using a simple playbook and the debug
module in it:
- name: Check the system facts
hosts: all
tasks:
- name: Facts
ansible.builtin.debug:
var: ansible_facts
To use conditional statements in playbooks with the when
directive simply add it to the task like this:
- name: Using the when conditional statement
hosts: all
tasks:
- name: Running a command on Debian OS family
command: uname -r
when: ansible_facts["os_family"] == "Debian"
Running this playbook with our inventory will cause that the task will run only on operating systems with Debian OS family. On Red Hat based systems the task will not run and following will be seen:
skipping: [192.168.1.93]
In the play recap you will see the skipped task for the host:
192.168.1.93 : (...) skipped=1 (...)
It is enough for you to start writing playbooks that can work on different operating systems like Debian and Rocky.
Loops in Ansible
Loops enable you to repeat tasks for multiple items. Whether you’re changing ownership, creating users, or polling for results, loops simplify your playbooks.
For example, if you want to add multiple users to a system you can use the loop
keyword to construct this task:
- name: Add users to the system
ansible.builtin.user:
name: "{{ item }}"
state: present
groups: "sudo"
loop:
- user1
- user2
- user3
The {{ item }}
loop variable is substituted in every iteration reading the list after the loop
keyword. The quotation marks this case are mandatory around the variable.
It is possible to iterate list of hashes (associative arrays) too.
- name: Loops in Ansible
hosts: all
tasks:
- name: Add users to the system
ansible.builtin.user:
name: "{{ item.name }}"
state: present
groups: "{{ item.group }}"
create_home: "{{ item.home }}"
loop:
- { name: user1, home: false, group: wheel }
- { name: user2, home: true, group: sudo }
- { name: user3, home: true, group: sudo }
Remember, mastering conditionals and loops in Ansible will make your playbooks more dynamic and adaptable.
Combining conditionals with loops
When you combine a when
statement with a loop, Ansible processes the condition separately for each item in the loop. This flexibility allows you to execute tasks selectively.
- name: Loops in Ansible
hosts: all
tasks:
- name: Add users to the system
ansible.builtin.user:
name: "{{ item.name }}"
state: present
groups: "{{ item.group }}"
create_home: "{{ item.home }}"
loop:
- { name: user1, home: false, group: wheel }
- { name: user2, home: true, group: wheel }
- { name: user3, home: true, group: wheel }
when: ansible_facts["os_family"] == "RedHat"
The above example will run the loop on machines that fulfills the condition, so their os_family
fact is RedHat
.
If you want to discuss the topic with other technology-minded people, join my Discord: https://discord.gg/YbSYGsQYES
Now we have an IRC channel as well: irc.libera.chat / #tomsitcafe