Updated April 1, 2023
Introduction to Ansible changed_when
Ansible changed_when property or parameters is defined to deal with the output of the specific task once a task is triggered on the remote node and based on the return code or the output, we can determine whether the task should be reported in the ansible statistic or need to use the trigger to handle the condition and the condition can be joined with the operators like “AND” means task only triggers when multiple conditions are met and with the “OR” operator when any of the conditions are met.
Syntax
The syntax for this command is changed_when.
How does the changed_when command work in ansible?
We use the changed_when command when we want to execute the task when the output has been changed based on the condition. To understand how changed_when works, we will use the below example.
We have the below ansible-playbook, which gets the content from the text file. In this playbook, we are mentioning the file which doesn’t exist. Below is the playbook.
---
- name: Ansible playbook to test changed_when condition
hosts: winservers
tasks:
- name: Get the content from the file
win_shell: gc c:\temp\servers22.txt
Playbook execution,
ansible-playbook servicepb.yml
Output:
If we see the output, the task shows it is failed, and that is expected. So let’s add the ignore_errors parameter to ignore this error.
tasks:
- name: Get the content from the file
win_shell: gc c:\temp\servers22.txt
ignore_errors: true
Playbook execution,
ansible-playbook servicepb.yml
Output:
If we check the output, after ignoring the error, playbook output says something is changed, but in fact, nothing has been changed. We can deal with the changed values with the changed_when parameter. First, we need to know the output from the task, and for that, we need to store the output to the variable using the register parameter and retrieve the output using the debug task as shown below.
tasks:
- name: Get the content from the file
win_shell: gc c:\temp\servers22.txt
register: dirvar
ignore_errors: true
- debug:
msg: "{{ dirvar}}"
Output:
Once you check the output, we can use the variable output to filter our result. We can apply changed_when to change the output, as shown below.
tasks:
- name: Get the content from the file
win_shell: gc c:\temp\servers22.txt
register: dirvar
ignore_errors: true
changed_when: "'Cannot find path' not in dirvar.stderr"
Playbook execution,
ansible-playbook servicepb.yml
Output:
If we check the output in the play recap section, it is now OK instead of the changed because we have specified that if “cannot find the path” is not there in the output, it will highlight the changed output.
changed_when command is different than the when and failed_when conditions, where we use the “when” condition to run the task only some condition satisfied while with the “failed_when” can be used to fail the task when some or all conditions are satisfied.
Examples of Ansible changed_when
Given below are the examples of Ansible changed_when:
Example #1
Changing the playbook output if the file content doesn’t match.
In this example, the playbook will retrieve the text file content from the remote windows servers, as shown below.
---
- name: Ansible playbook to test changed_when condition
hosts: winservers
tasks:
- name: Get the content from the file
win_shell: gc c:\temp\servers.txt
register: dirvar
ignore_errors: true
- debug:
msg: "{{dirvar.stdout}}"
Playbook execution,
ansible-playbook servicepb.yml
Output:
Its output changed=1; we need that if the servers.txt file contains “AD”, then only the output should be displayed as changed; otherwise, it should be OK. So we will put the changed_when condition inside the task.
tasks:
- name: Get the content from the file
win_shell: gc c:\temp\servers.txt
register: dirvar
ignore_errors: true
changed_when: dirvar.stdout.find('AD')==0
- debug:
msg: "{{dirvar.stdout}}"
Once we run the output server, .202 should not change the value because it doesn’t contain “AD”, but server .206 server contains, and it can be seen in the below output.
Playbook execution,
ansible-playbook servicepb.yml
Example #2
changed_when with the multiple conditions.
We can use the changed_when parameter with the multiple conditions, as explained in this example.
---
- name: Ansible playbook to test changed_when condition
hosts: winservers
tasks:
- name: Check the spooler service
win_shell: get-service spooler | Select Status, StartType
register: servicevar
ignore_errors: true
changed_when: (servicevar.stdout.find("Stopped")==40) and (servicevar.stdout.find("Manual")==52)
In the above example, we are using multiple conditions and combining both them with the ‘and’ operator. So if the spooler service is stopped and in the manual mode, then the service output changed; otherwise, it will be OK.
We can also use the or operator for the same, so if any condition is true the output is true.
changed_when: (servicevar.stdout.find("Stopped")==40) or (servicevar.stdout.find("Manual")==52)
You can also provide the multiple conditions as shown below. It is similar to the “OR” condition.
tasks:
- name: Check the spooler service
win_shell: get-service spooler | Select Status, StartType
register: servicevar
ignore_errors: true
changed_when:
- servicevar.stdout.find("Stopped")==40
- servicevar.stdout.find("Manual")==52
Example #3
changed_when example with Pagefile settings on windows.
In this example, we are querying the pagefile on the remote windows servers, as shown below.
---
- name: Playbook to query the pagefile settings.
hosts: winservers
tasks:
- name: Query C drive pagefile
win_pagefile:
drive: c
register: pagevar
- debug:
msg: "{{ pagevar }}"
Playbook execution,
ansible-playbook pagefilequery.yml
Output:
We need here when the pagefile initial_size and maximum_size are 0; then we need the task should highlight the “changed” value. So we will use the JSON query and modify the playbook as below.
tasks:
- name: Query C drive pagefile
win_pagefile:
drive: c
register: pagevar
changed_when: (pagevar | json_query('pagefiles[*].initial_size | [0]') == 0) and (pagevar | json_query('pagefiles[*].maximum_size | [0]') == 0)
- debug:
msg: "{{pagevar}}"
Playbook execution,
ansible-playbook pagefilequery.yml
Output:
You can see for the server .202 changed value is highlighted.
Conclusion
Ansible changed_when condition is useful when we need to take the corrective decision related to the task output. For example, sometimes, we need the task should display changed based on the output even when it doesn’t do anything and vice versa. So even if the task says the result is OK, but we didn’t get the desired outcome, then we can use the changed_when parameter.
Recommended Articles
This is a guide to Ansible changed_when. Here we discuss How does the changed_when command work in ansible along with the examples. You may also have a look at the following articles to learn more –