Ansible Basics 06: Conditional Statements and Loops

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

Leave a comment