In my Ansible playbook I have this:

- name: "A: Check to see if we need to run task B"
  [... implementation omitted, not relevant ...]
  register: task_a_result
  check_mode: no  # even run in check mode
  changed_when: no  # this only reads/checks stuff

- name: "B: Write x to file"
  shell: "echo {{ my_var|quote }} > /path/to/file"
  when: task_a_result.stdout_lines[0].startswith('ABCDEF')
  changed_when: yes  # when run, it always changes the state

I do not want to run B in check mode (hence, no check_mode: no), but I want to report it as changed if it would have been run in non-check mode. I want this behaviour, because I do not want surprises when running in non-check mode. However, despite having changed_when: yes and having set a conditional myself, Ansible keeps showing the task as skipped and thus unchanged to me:

skipping: [myhost] => changed=false 
  msg: skipped, running in check mode

(The above in check mode, and it reports 'changed' in regular non-check mode.)

I found this bug report that appears misinterpreted and closed inappropriately: 14950, but I cannot comment on that any longer.

Am I overlooking something basic? Other modules usually report a "would have changed" status perfectly fine in Ansible, but is this also possible for shell/command?

Using Ansible 2.7.12 and 2.8.2 yields the same results.

I am hoping to avoid nasty hacks in the command itself like:

- name: "B: Write x to file"
  shell: "echo {{ my_var|quote }} {{ '>' if task_a_result.stdout_lines[0].startswith('ABCDEF') else '' }} /path/to/file"
  when: task_a_result.stdout_lines[0].startswith('ABCDEF')
  changed_when: yes

And yes I know I can write to a file with the copy/template modules, but I can't seem to overwrite files with it, e.g. echo 1234 > /sys/module/zfs/parameters/zfs_arc_max, because copy/template would attempt to replace the file it seems and setting a kernel parameter wouldn't work like that. And no, this kernel module parameter is not exposed through sysctl on Linux.

  • Why does it matter? – Michael Hampton Jul 24 '19 at 0:41
  • @MichaelHampton Because in a check mode, I'd like to know if something would change if I run it in non-check mode. IOW, without Ansible, if you would run cmd --dry-run which outputs "nothing changed" and you would then do cmd, and it would change something, this would be a bug. – gertvdijk Jul 24 '19 at 12:12
  • But you've set the play to always report changed even if nothing changed (which is redundant). It certainly looks like the actual result is irrelevant, doubly so in check mode. What is missing here? – Michael Hampton Jul 24 '19 at 15:07
  • @MichaelHampton when: my_conditional_var determines whether the task is going to run, and if it runs, it will change. I want to see that in check mode. Perhaps I could improve the wording in the Q? It's basically check mode reports "I'm not going to change anything" and in non-check mode it will change stuff. That's what I want to fix. – gertvdijk Jul 25 '19 at 0:16
  • In the example you gave, it doesn't actually matter! You can just ignore it. Are you doing something else? – Michael Hampton Jul 25 '19 at 6:04

I have a similar need. I would like to see if the command would be run so that I get no surprises when not run in check mode.

As a workaround I added a debug task reporting that there would be a change and used the when condition from the command task to set changed_when on the debug task, i.e.

- name: "Report pending change"
    msg: "Change pending"
  changed_when: task_a_result.stdout_lines[0].startswith('ABCDEF')
  when: ansible_check_mode|bool
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.