Using when to Run Tasks Conditionally
Using when to Run Tasks Conditionally
- Use a when statement to run tasks conditionally.
- you can test whether:
- a variable has a specific value
- whether a file exists
- whether a minimal amount of memory is available
- etc.
Working with when
Install the right software package for the Apache web server, based on the Linux distribution that was found in the Ansible facts. Notice that
- when used in when statements, the variable that is evaluated is not placed between double curly braces.
-
not a part of any properties of the modules on which it is used
-
must be indented at the same level as the module itself.
-
For a string test, the string itself must be between double quotes.
-
Without the double quotes, it would be considered an integer test.
Using Conditional Test Statements
Common conditional tests that you can perform with the when statement:
Variable exists
-
variable is defined Variable does not exist
-
variable is not defined First variable is present in list mentioned as second
-
ansible_distribution in distributions Variable is true, 1 or yes
-
variable Variable is false, 0 or no
-
not variable Equal (string)
-
key == “value” Equal (numeric)
-
key == value Less than
-
key < value Less than or equal to
-
key <= value Greater than
-
key > value Greater than or equal to
-
key >= value Not equal to
-
key != value
-
Look for “Tests” in the Ansible documentation, and use the item that is found in Templating (Jinja2).
-
When referring to variables in when statements, you don’t have to use curly brackets because items in a when statement are considered to be variables by default.
-
So you can write when: text == “hello” instead of when: “{{ text }}” == “hello”.
There are roughly four types of when conditional tests: • Checks related to variable existence • Boolean checks • String comparisons • Integer comparisons
The first type of test checks whether a variable exists or is a part of another variable, such as a list.
Checks for the existence of a specific disk device, using variable is defined and variable is not defined. All failing tests result in the message “skipping.”
Lab: Check that finds whether the first variable value is present in the second variable’s list.
- executes the debug task if the variable my_answer is in supported_packages.
- vars_prompt is used. This stops the playbook, asks the user for input, and stores the input in a variable with the name my_answer.
Boolean check
- Works on variables that have a Boolean value (not very common) T
- Should not be defined with the check for existence.
- Used to check whether a variable is defined.
string comparisons and integer comparisons
- Ie: Check if more than 1 GB of disk space is available.
- When doing checks on available disk space and available memory, carefully look at the expected value.
- Memory is shown in megabytes, by default, whereas disk space is expressed in bytes.
Lab: integer check, install vsftpd if more than 50 MB of memory is available.
Testing Multiple Conditions
- when statements can also be used to evaluate multiple conditions.
- To do so, you can group the conditions with parentheses and combine them with and and or keywords.
- and runs if both conditionals are ture
- or runs if one of the conditions are true
Lab: and is used and runs the task only if both conditions are true.
- You can make more complex statements by grouping conditions together in parentheses.
- group the when statement starts with a > sign to wrap the statement over the next five lines for readability.
Lab: Combining complex statements
Combining loop and when
Lab: Combining loop and when, Perform a kernel update only if /boot is on a dedicated mount point and at least 200 MBis available in the mount.
Combining loop and register
Lab: Combining register and loop
passwd_contents.stdout.find,
- passwd_contents.stdout does not contain any item with the name find.
- Construction that is used here is variable.find, which enables a task to search a specific string in a variable. (thefind function in Python is used)
- When the Python find function does not find a string, it returns a value of −1.
- If the requested string is found, the find function returns an integer that returns the position where the string was found.
- For instance, if the string lisa is found in /etc/passwd, it returns an unexpected value like 2604, which is the position in the file, expressed as a byte offset from the beginning, where the string is found for the first time.
- Because of the behavior of the Python find function, variable.find needs not to be equal to −1 to have the task succeed. So don’t write passwd_contents.stdout.find(’lisa’) = 0 (because it is not a Boolean), but instead write passwd_contents.stdout.find(’lisa’) != -1.
Lab: Practice working with conditionals using register.
- When using register, you might want to define a task that runs a command that will fail, just to capture the return code of that command, after which the playbook should continue. If that is the case, you must ensure that ignore_errors: yes is used in the task definition.
1. Use your editor to create a new file with the name exercise72.yaml. Start writing the play header as follows:
2. Add the first task, which checks whether the httpd service is running, using command output that will be registered. Notice the use of ignore_errors: yes. This line makes sure that if the service is not running, the play is still executed further.
3. Add a debug task that shows the output of the command so that you can analyze what is currently in the registered variable:
4. Complete the playbook by including the service task, which is started only if the value stored in result.rc (which is the return code of the command that was registered) contains a 0. This is the case if the previous command executed successfully.
5. Use an ad hoc command to make sure the httpd service is installed: ansible ansible1 -m yum -a "name=httpd state=latest".
6. Use an ad hoc command to make sure the httpd service is stopped: ansible ansible1 -m service -a "name=httpd state=stopped".
7. Run the playbook using ansible-playbook exercise72.yaml and analyze the result. You should see that the playbook skips the service task.
8. Type ansible ansible1 -m service -a "name=httpd state=started" and run the playbook again, using ansible-playbook exercise72.yaml. Playbook execution at this point should be successful.