Ansible conditioning, also known as conditional statements, allows you to execute tasks in a playbook based on specific conditions. This feature makes your playbooks more dynamic and adaptable to different environments and scenarios. Conditions are specified using the when
keyword.
Using Conditions in Ansible
Conditions in Ansible are typically based on:
- Facts gathered about the host
- Variables
- The results of previous tasks
Basic Syntax
The when
keyword is used to define conditions. Here’s the basic syntax:
tasks:
- name: Install Apache on Debian-based systems
ansible.builtin.apt:
name: apache2
state: present
when: ansible_facts['os_family'] == "Debian"
Examples of Conditional Statements
Using Facts:
tasks:
- name: Install Apache on Debian-based systems
ansible.builtin.apt:
name: apache2
state: present
when: ansible_facts['os_family'] == "Debian"
- name: Install httpd on RedHat-based systems
ansible.builtin.yum:
name: httpd
state: present
when: ansible_facts['os_family'] == "RedHat"
Using Variables:
tasks:
- name: Install a package based on a variable
ansible.builtin.apt:
name: "{{ package_name }}"
state: present
when: package_name is defined
Combining Multiple Conditions:
tasks:
- name: Install Apache only on Debian-based systems with specific versions
ansible.builtin.apt:
name: apache2
state: present
when:
- ansible_facts['os_family'] == "Debian"
- ansible_facts['distribution_version'] == "10"
Using the Results of Previous Tasks:
tasks:
- name: Check if a file exists
ansible.builtin.stat:
path: /path/to/file
register: file_check
- name: Create the file if it does not exist
ansible.builtin.file:
path: /path/to/file
state: touch
when: not file_check.stat.exists
Advanced Conditions
You can also use Jinja2 expressions to create more complex conditions:
Checking for Multiple Conditions with Logical Operators:
tasks:
- name: Ensure the package is installed only if conditions are met
ansible.builtin.apt:
name: "{{ package_name }}"
state: present
when: (ansible_facts['os_family'] == 'Debian' and ansible_facts['distribution_version'] == '10') or (ansible_facts['os_family'] == 'RedHat' and ansible_facts['distribution_major_version'] == '7')
Using ansible_facts
and Variables Together:
tasks:
- name: Restart Apache if it's running
ansible.builtin.service:
name: apache2
state: restarted
when: ansible_facts['os_family'] == "Debian" and (ansible_facts['distribution_version'] == "10" or custom_condition == true)
Using failed_when
and changed_when
In addition to using conditions for task execution, you can also control the success and failure criteria of a task using failed_when
and changed_when
:
failed_when
:
tasks:
- name: Check for specific string in a file
ansible.builtin.command: cat /path/to/file
register: file_content
failed_when: "'specific string' not in file_content.stdout"
changed_when
:
tasks:
- name: Ensure a line is in the file
ansible.builtin.lineinfile:
path: /path/to/file
line: "specific line"
register: line_result
changed_when: line_result.changed
Other examples
---
- name: Update web servers
hosts: web
vars:
myname: "Rajesh Kumar"
tasks:
- name: Install Apache in centos7
ansible.builtin.yum:
name: httpd
state: latest
when: ( ansible_os_family == "RedHat" and ansible_system == "Linux")
- name: Copy index.html
ansible.builtin.copy:
src: index.html
dest: /var/www/html/index.html
- name: Starting a Apache Server
ansible.builtin.service:
name: httpd
state: started
when:
- ansible_os_family == "RedHat"
- ansible_distribution_major_version == "7"
- ansible_system == "Linux"
- name: My Name is Equals to Rajesh Kumar
debug:
msg: "My Name is Equals to Rajesh Kumar"
when: myname == "Rajesh Kumar"
- name: Ansible print when ubuntu
debug:
msg: "I am ubuntu"
when: ansible_os_family == "Debian"
- name: My Name is not Equals to Rajesh Kumar
debug:
msg: "My Name is not Equals to Rajesh Kumar"
when: myname != "Rajesh Kumar"
# We can also check if a variable is empty using similar manner.
- hosts: all
tasks:
- shell: cat /etc/temp.txt
register: output
- name: Ansible when variable is empty example
debug:
msg: "empty"
when: output.stdout == ""
---
# this is a demo of conditional executions using 'when' statements, which can skip
# certain tasks on machines/platforms/etc where they do not apply.
- hosts: all
remote_user: root
vars:
favcolor: "red"
dog: "fido"
cat: "whiskers"
ssn: 8675309
tasks:
- name: "do this if my favcolor is blue, and my dog is named fido"
shell: /bin/false
when: favcolor == 'blue' and dog == 'fido'
- name: "do this if my favcolor is not blue, and my dog is named fido"
shell: /bin/true
when: favcolor != 'blue' and dog == 'fido'
- name: "do this if my SSN is over 9000"
shell: /bin/true
when: ssn > 9000
- name: "do this if I have one of these SSNs"
shell: /bin/true
when: ssn in [ 8675309, 8675310, 8675311 ]
- name: "do this if a variable named hippo is NOT defined"
shell: /bin/true
when: hippo is not defined
- name: "do this if a variable named hippo is defined"
shell: /bin/true
when: hippo is defined
For Ubuntu
- name: Update web servers
hosts: web
vars:
myname: "Rajesh Kumar"
tasks:
- name: Install Apache in ubuntu
ansible.builtin.apt:
name: apache2
state: latest
when: ( ansible_os_family == "Debian" and ansible_system == "Linux")
- name: Copy index.html
ansible.builtin.copy:
src: index.html
dest: /var/www/html/index.html
- name: Starting a Apache Server
ansible.builtin.service:
name: apache2
state: started
when:
- ansible_os_family == "Debian"
- ansible_distribution_major_version == "20"
- ansible_system == "Linux"
- name: My Name is Equals to Rajesh Kumar
debug:
msg: "My Name is Equals to Rajesh Kumar"
when: myname == "Rajesh Kumar"
- name: Ansible print when ubuntu
debug:
msg: "I am ubuntu"
when: ansible_os_family == "Debian"
- name: My Name is not Equals to Rajesh Kumar
debug:
msg: "My Name is not Equals to Rajesh Kumar"
when: myname != "Rajesh Kumar"