'How do I create an Ansible "pre-handler" that runs before the task but only if the task needs to run?
How do I create an Ansible "pre-handler" that runs before the task, but only if the task needs to run? In other words, Ansible will first check if the task needs to be run. If it does, it runs the pre-handler and then runs the task. If the task does not need to be run, the pre-handler is never run.
My use case is a root filesystem mounted as read-only. I have an Ansible task to create .bashrc
. I would like Ansible to remount the filesystem as read-write if and only if .bashrc
needs to be updated. Remounting the filesystem before and after each Ansible run is not practical because making it read-only again requires a reboot.
Solution 1:[1]
A handler is notified by a task if that task changed something. So a "pre-handler" is not possible as the task needs to run to see if it changes something or not.
However, you can notify a handler from a task running in check mode. If you want to do things in order, you'll need to force the run of handlers with the meta
module.
Would something like the below example solve your problem ?
- name: Check if .bashrc has the correct content
copy: &bashrc_copy_params
src: bashrc_root
dest: /root/.bashrc
owner: root
group: root
mode: 0644
check_mode: true
notify: remount root fs rw
- meta: flush_handlers
- name: Really copy .bashrc
copy: *bashrc_copy_params
Note that you can achieve the exact same result without a handler in this specific case. Below, an other example with a block that will run only when the check reports a change. It is even better than the previous example as the real copy task will be totally skipped if not needed.
- name: Check if .bashrc has the correct content
copy: &bashrc_copy_params
src: bashrc_root
dest: /root/.bashrc
owner: root
group: root
mode: 0644
check_mode: true
register: bashrc_state
- when: bashrc_state.changed | bool
block:
- name: remount root fs rw
debug:
msg: for example only, replace with your own task
- name: Really copy .bashrc
copy: *bashrc_copy_params
Note: The &bashrc_copy_params
and *bashrc_copy_params
notations in my above examples are yaml anchors. See learn yaml in Y minutes for an explanation if needed. They are allowed in Ansible but must be declared and used in the same file.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |