There is an undocumented
* but intentional interaction
between
ansible.builtin.set_fact
and the
run_once parameter.
You are in luck, because it solves exactly this problem in a clean
way. When you use
set_fact to
create a variable with
run_once: true,
it sets the variable for all hosts in the play. So you can say:
- name: Snarf the playbook start time on all hosts
ansible.builtin.set_fact:
ansible_playbook_starttime: "{{ now('True', '%F_%H%M%S') }}"
run_once: true
After this step runs, all hosts will have the same
ansible_playbook_starttime variable
with a fully templated out value.
This differs from, say, setting the same variable in
group_vars/all or in your playbook's
vars: section. If you create
the variable any of these other ways, "lazy evaluation" will cause
the variable's template to be re-evaluated each time it is used. In
contrast,
set_fact will
produce ‘static’ values, i.e. not subject to or requiring further
template evaluation on subsequent uses.
*Arguably one could read ansible-doc
-t module set_fact with a lawyer's eye and discern
this behavior, but I've read it a dozen or more times and never
once did it occur to me that run_once:
true would have this effect across all hosts. There
is a bug
report about it from October 2018 that spells it out.
Otherwise it's one of those serendipitous discoveries that either
makes your day or ruins your weekend.