summaryrefslogtreecommitdiffstats
path: root/src/ansiblelint/rules/no_changed_when.md
blob: 95c1d46f1eb0538fc896e0237d6d2deb61991475 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# no-changed-when

This rule checks that tasks return changes to results or conditions. Unless
tasks only read information, you should ensure that they return changes in the
following ways:

- Register results or conditions and use the `changed_when` clause.
- Use the `creates` or `removes` argument.

You should always use the `changed_when` clause on tasks that do not naturally
detect if a change has occurred or not. Some of the most common examples are
[shell] and [command] modules, which run arbitrary commands.

One very common workaround is to use a boolean value like `changed_when: false`
if the task never changes anything or `changed_when: true` if it always changes
something, but you can also use any expressions, including ones that use the
registered result of a task, like in our example below.

This rule also applies to handlers, not only to tasks because they are also
tasks.

## Problematic Code

```yaml
---
- name: Example playbook
  hosts: localhost
  tasks:
    - name: Does not handle any output or return codes
      ansible.builtin.command: cat {{ my_file | quote }} # <- Does not handle the command output.
```

## Correct Code

```yaml
---
- name: Example playbook
  hosts: localhost
  tasks:
    - name: Handle shell output with return code
      ansible.builtin.command: cat {{ my_file | quote }}
      register: my_output # <- Registers the command output.
      changed_when: my_output.rc != 0 # <- Uses the return code to define when the task has changed.
```

[shell]:
  https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html
[command]:
  https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html