Ansible

Ansible Changed_When

Ansible is a powerful, accessible, and open-source automation tool that offers immense functionality combined with simple and declarative language.

Ansible provides an idempotent nature which allows it only to make the defined changes when necessary. But how does Ansible decide if a task changed something on a remote system?

More often than not, the default behavior suffices. However, we might sometimes need to specify the custom conditions to decide if a task made any changes. Enter the “changed_when” directive.

The “changed_when” directive allows us to define when a task should be marked as “changed” which can be based on the outcome of the task or even on the results of other tasks.

Ansible Changed_When

In Ansible, you can specify the conditions under which a task is deemed to have “modified” a remote host using the “changed_when” directive.

This provision allows you to decide, grounded on outputs or return values, if Ansible should record a change in its metrics and if an associated handler needs activation.

Example 1: Basic Example

Let us explore an essential playbook to use the “changed_when” directive.

Suppose we have a shell command that outputs a random number between 1 and 5. Suppose we only want to consider the task changed if the random number is 3.

We can define the playbook as follows:

---
- hosts: localhost
  tasks:
    - name: Generate a random number
      command: echo $((1 + RANDOM % 5))
      register: result
      changed_when: "'3' in result.stdout"

The given playbook uses the “register” directive to capture the command output. We then use the “changed_when” directive to check if the output has the number 3. If true, Ansible marks the task as changed.

Example 2: Ansible File Manipulation

We can also use the “changed_when” directive in file manipulation. For example, suppose we are trying to append a given entry to a file but only want the task marked as changed if the entry does not exist.

We can define a playbook as follows:

---
- hosts: localhost
  tasks:
    - name: Check if entry exists in file
      command: grep 'ff02::1 ip6-allnodes' /etc/hosts
      register: grep_result
      failed_when: false
      changed_when: false
    - name: Append line to file
      lineinfile:
        path: /etc/hosts
        line: 'ff02::1 ip6-allnodes'
      when: grep_result.rc != 0
      changed_when: true

In this example, we check if the entry exists in the target file. The task will never be marked as changed because of the “changed_when: false”. The second task appends the entry if it doesn’t exist.

Example 3: Complex Queries

We can also create complex and more precise conditions by chaining multiple commands and tools. For example, suppose we want to check the disk usage and only mark the task as changed when the disk usage exceeds to 90%.

We can define a playbook to accomplish the previous task as follows:

---
- hosts: localhost
  tasks:
    - name: Check disk usage
    command: df -h / | awk 'NR==2 {print $5}' | cut -d'%' -f1
    register: disk_usage
    changed_when: disk_usage.stdout|int > 90

In this example, we combine the df, awk, and cut commands to check the disk usage percentage. We then use the “changed_when” parameter to mark the task as changed when the specified condition is true.

Conclusion

As discussed in this tutorial, the “changed_when” directive gives us the flexibility to define the custom conditions for determining whether an Ansible task has made changes. Hence, it offers more granular control over the changed status of a task, ensuring that our playbooks accurately represent the state of the target systems.

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list