Reputation: 57126
With the command module, if the command creates a file, you can check to see if that file exists. If it does it prevents the command executing again.
- command: touch ~/myfile
args:
creates: ~/myfile
However, if the command does not create a file then on a re-run it executes again.
To avoid a second execution, I create some random file on a change (notify) as follows:
- command: dothisonceonly # this does not create a file
args:
creates: ~/somefile
notify: done
then the handler:
- name: done
command: touch ~/somefile
This approach works but is a bit ugly. Can anyone shed let on best practice? Maybe setting some fact? Maybe a whole new approach?
Upvotes: 1
Views: 1029
Reputation: 57126
This is my actual implementation based on the answer by @techraf
- command: echo 'phew'
register: itworks
notify: Done itworks
when: ansible_local.itworks | d(0) == 0
and handler:
- name: Done itworks
copy:
content: '{{ itworks }}'
dest: /etc/ansible/facts.d/itworks.fact
Docs:
http://docs.ansible.com/ansible/playbooks_variables.html#local-facts-facts-d
Thanks @techraf this works great and persists facts.
EDIT
Applied default value logic in @techraf's comment.
Upvotes: 1
Reputation: 9353
Ideally with Ansible, check for the state that was changed by the first command rather than using a file as a proxy. The reason being that checking the actual state of something provides better immutability since it is tested on every pass.
If there is a reason not to use that approach. Then register the result of the command and use that instead of a notifier to trigger creation of the file.
- command: dothisonceonly # this does not create a file
creates: ~/somefile
register: result
- file:
path: ~/somefile
state: touch
when: result|succeeded
If you are curious to see what is happening here, add:
- debug: var=result
Be aware with notifiers that they are run at the end of the play. This means that if a notifier is triggered by a task but then then play fails to complete, the notifier will not be run. Conversely there are Ansible options which cause notifiers to run even when not triggered by tasks.
Upvotes: 3
Reputation: 68589
It is a fact (in common language) that a command was run successfully on a specific target host, so the most appropriate would be to use local facts (in Ansible vernacular).
In your handler save the state as a JSON file under /etc/ansible/facts.d
with copy
module and content
parameter.
It will be retrieved and accessible whenever you run a play against the host with a regular fact-gathering process.
Then you can control the tasks with when
condition (you need to include the default
filter for the situation when no fact exists yet).
Upvotes: 4