Ansible: Running Commands in Dry-Run Mode in Check Mode
Say you have an Ansible playbook that invokes a command. Normally, that command executes when you run ansible
normally, and doesn’t execute at all when you run ansible
in check mode.
But a lot of commands, like rsync
have a -n
or --dry-run
argument that shows what would be done, without actually making any changes. So it would be nice to combine the two.
Let’s start with a simple playbook that copies some files with rsync
:
- name: Copy files tasks: - name: rsync the files command: >- rsync -avi /tmp/source/ /tmp/destination/ hosts: localhost become: no gather_facts: no
When you execute this playboook with ansible-playbook foo.yml
rsync
runs, and when you run in check mode, with ansible-playbook -C foo.yml
, rsync
doesn’t run.
This is inconvenient, because we’d like to see what rsync
would have done before we commit to doing it. So let’s force it to run even in check mode, with check_mode: no
, but also run rsync
in dry-run mode, so we don’t make changes while we’re still debugging the playbook:
- name: Copy files tasks: - name: rsync the files command: >- rsync --dry-run -avi /tmp/source/ /tmp/destination/ check_mode: no hosts: localhost become: no gather_facts: no
Now we just need to remember to remove the --dry-run
argument when we’re ready to run it for real. And turn it back on again when we need to debug the playbook.
Or we could do the smart thing, and try to add that argument only when we’re running Ansible in check mode. Thankfully, there’s a variable for that: ansible_check_mode
, so we can set the argument dynamically:
- name: Copy files
tasks:
- name: rsync the files
command: >-
rsync
{{ '--dry-run' if ansible_check_mode else '' }}
-avi
/tmp/source/
/tmp/destination/
check_mode: no
hosts: localhost
become: no
gather_facts: no
You can check that this works with ansible-playbook -v -C foo.yml
and ansible-playbook -v foo.yml
.