Ansible: Using changed_when in playbook

This post shows how to use changed_when in playbook of Ansible.
It is one of the important elements to write playbook with idempodency.

When changed_when is required

I explain about the following example playbook.

---
- name: Test Playbook
  hosts: 192.168.1.1

  tasks:
  - name: Absent tmp folder
    win_shell: |
      $ret = Test-Path -Path C:\tmp
      if ($ret) {
        Remove-Item -Path C:\tmp -Force
      }

This playbook makes C:\tmp folder to be absent.
It deletes a folder only when it exists.
Though seemingly to be considered, this playbook shows result like the following regardless of existence of folder.

PLAY [Test Playbook] *****************************************************************************

TASK [Absent tmp folder] *************************************************************************
changed: [192.168.1.1]

PLAY RECAP ***************************************************************************************
192.168.1.1           : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

This playbook always shows changed=1 after run win_shell.

Using changed_when in Playbook

To show changed=1 only after deletion, Write playbook like the following.

---
- name: Test Playbook
  hosts: 192.168.1.1

  tasks:
  - name: Absent tmp folder
    win_shell: |
      $ret = Test-Path -Path C:\tmp
      if ($ret) {
        Remove-Item -Path C:\tmp -Force
        Write-Output 1
      }
    register: ret
    changed_when: (ret.stdout | int) == 1

If folder is deleted, write 1 to standard output.

        Write-Output 1

Store the returned value of win_shell in ret by register.

    register: ret

Refer to the following web site about the returned value of win_shell.
https://docs.ansible.com/ansible/2.9_ja/modules/win_shell_module.html#return-values

ret.stdout is standard output of win_shell. If standard output is 1, changed=1

    changed_when: (ret.stdout | int) == 1

To convert string 1 into a numeric 1, (ret.stdout | int)

That is about it.