Playbooks
Conditional checks
Conditional checks use the when:
syntax. When conditions can use raw Jinja2 expressions but can execute regular python code so can access methods like String.find() to check for a text match in a String. Multiple conditions should be enclosed with parenthesis, multiple conditions can be specified in a list where they are all required to be true (logical AND).
Conditional check examples
when:
- tomcat_status_result.stdout.find("JVM is running.") > -1
- tomcat_status_result.stderr != ""
- tomcat_status_result.rc == 0
---
- hosts: all
tasks:
- name: "print inventory vars"
debug:
var: "{{ item }}"
with_items:
- inventory_dir
- inventory_file
when: inventory_dir | regex_search('dev$')
- hosts: all
tasks:
- name: "apply stub role"
include_role:
name: issuer-wallet-stub
when: inventory_dir | regex_search('dev$')
Required variables
Often at the beginning of a Playbook or Role you may want to assert that all mandatory variables have been defined. This can avoid more difficult problems further into a playbook, like only finding this out mid-way through a production deployment.
vars.yml
REQUIRED_VARS:
- application_version # Exists
- i_dont_exist
- name: Ensure required variables have been set
assert:
that: lookup('vars', item) is defined
loop: "{{ REQUIRED_VARS }}"
delegate_to: localhost
run_once: Yes
By using a list of varaible names in vars.yml for example in an Ansible Role, it keeps all the variable declarations together. Note that you cannot use is defined
directly on {{ item }}
, you will get the following output (v2.10.4).
ok: [localhost] => (item=i_dont_exist) => {
"ansible_loop_var": "item",
"i_dont_exist": "VARIABLE IS NOT DEFINED!",
"item": "i_dont_exist"
}
Filters
See documentation on filters. Filters use Jinja2, and Ansible ships with some extra ones to those available in Jinja2. Remember that if using a filter in a conditional statement that python methods are also accessible.
Also note that the online Jinja2 documentation doesn't go back to python-jinja2 2.7 which is what is provided in RedHat repos for RHEL7. There are no RHEL plans to update Jinja2 to anything later, so what you read on the Jinja website will include features not available to Ansible on RHEL7, because of the Jinja2 version.
To select an item from a list, based on an attribute, use the selectattr with the match filter, as the equalsto filter is only available in Jinja2 2.8.
Given a yaml file like this,
projects:
- name: project-a
version: '2.3.4-SNAPSHOT'
- name: project-b
version: '1.2.3-SNAPSHOT'
- name: project-c
value: '5.6.7-SNAPSHOT'
Select the version of project-b using the following expression.
- hosts: project-hosts-b
vars:
- deployable_version: "{{ projects | selectattr('name', 'match', '^project-b$') | map(attribute='version') | list | first }}"
References
Debug
You can print a message with variable information in it, combine this with the verbosity level, below which the debug will not output anything.
- debug:
msg: "System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}"
verbosity: 4
when: ansible_default_ipv4.gateway is defined
See documentation for the debug module.
Play options
Disable facts gathering
- hosts: all
gather_facts: false
Import and Include
Ansible documentation on Creating reusable playbooks Note there are trade-offs when selecting between static and dynamic, any import* tasks will be static, any include* tasks will be dynamic.
- All
import*
statements are pre-processed at the time playbooks are parsed. - All
include*
statements are processed as they encountered during the execution of the playbook.