I am wondering that in some cases, ansible shows "changed=0" even playbook tasks were executed successfully and ok=2. This happens par example when working with Rest API and uri module. I tried to find an explanation without success. Can anyone advise what is the reason? If I make a change on many servers together where I am not checking manually that change was done, this will be a big problem. Thanks!
The key difference between 'changed' and 'ok' in Ansible is the internal agreement between all modules on what is 'ok' and what is 'changed'.
When a module think that it's action changed something (e.g. a state of a subject before module execution and a state after are different), it need to report 'changed' to Ansible. If there were no meaningful changes (definition of 'meaningful' is left to the module), than it reports 'ok'. Sometime modules can detect in advance if changes are needed (example: There is no need to create a directory, as it already exists), sometime it can be detected only after execution of the action (f.e. some application reported 'not changed' to the attempted reconfiguration).
Now let's look to url module. How can url module to guess if something have been changed on a remote http/s server after request? The truth is, that it can sometimes. If server answered with something like 'updated', the module can report 'changed' back. But what to do if server answer is '200 OK'? So, there is no 'changed' here.
What to do?
Ansible have a feature: you can override the default module 'changed' status by stating condition for 'changed'.
Example
This is an example from my real configuration for API server:
uri:
method: POST
url: http://{{ api_address }}:{{api_port }}/config
body_format: raw
headers:
Content-Type: text/plain
body: '{{ {"global_config": global_config} |to_yaml }}'
status_code:
- 200
- 304
- 201
register: config_post
changed_when: config_post.status == 200 or config_post.status == 201
As you can see we have an agreement that '200 or 201' is 'changed', and '304' is not changed (but ok). This agreement is supported by server and by Ansible role.
For less precise situation, you can just say changed_when: True and your task will always be 'changed' (except for failures and skips).
In a nutshell:
changed means that the module implemented the change it is supposed to implementok means the there is no need for that change.For example: if you are copying a file to the remote node, the module debugs change=1 if the file doesn't exist on the remote destination and is explicitly copied by the ansible module, whereas it debugs ok=1 when the file already exists on the remote node with the same name and content.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With