Enable cache. For example,
shell> grep fact_caching ansible.cfg
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_cache
fact_caching_prefix = ansible_facts_
fact_caching_timeout = 86400
Given the inventory
shell> ansible-inventory --graph --yaml
@all:
|--@example_org:
| |--master
| |--replica
|--@ungrouped:
| |--localhost
The playbook runs setup on all hosts and caches both the facts and the dictionary default_ipv4 created by set_fact
shell> cat pb.yml
- hosts: all
gather_facts: false
tasks:
- setup:
gather_subset:
- default_ipv4
- set_fact:
default_ipv4:
master: "{{ hostvars.master.ansible_default_ipv4.address }}"
replica: "{{ hostvars.replica.ansible_default_ipv4.address }}"
cacheable: true
run_once: true
- debug:
var: default_ipv4
run_once: true
gives
shell> ansible-playbook pb.yml
PLAY [all] ***********************************************************************************
TASK [setup] *********************************************************************************
ok: [localhost]
ok: [master]
ok: [replica]
TASK [set_fact] ******************************************************************************
ok: [localhost]
TASK [debug] *********************************************************************************
ok: [localhost] =>
default_ipv4:
master: 192.168.1.242
replica: 10.1.0.61
PLAY RECAP ***********************************************************************************
localhost: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
master: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
replica: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The facts including the dictionary default_ipv4 were cached
shell>tree /tmp/ansible_cache/
/tmp/ansible_cache/
├── ansible_facts_localhost
├── ansible_facts_master
└── ansible_facts_replica
The cache of all hosts from the inventory will be available also to a single host running the playbook. For example,
shell> ansible-playbook pb.yml -l master
PLAY [all] ***********************************************************************************
TASK [setup] *********************************************************************************
ok: [master]
TASK [set_fact] ******************************************************************************
ok: [master]
TASK [debug] *********************************************************************************
ok: [master] =>
default_ipv4:
master: 192.168.1.242
replica: 10.1.0.61
PLAY RECAP ***********************************************************************************
master: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
If the facts are cached you can run the play with serial: 1
shell> cat pb.yml
- hosts: all
serial: 1
gather_facts: false
...
gives
shell> ansible-playbook pb.yml
PLAY [all] ***********************************************************************************
TASK [setup] *********************************************************************************
ok: [localhost]
TASK [set_fact] ******************************************************************************
ok: [localhost]
TASK [debug] *********************************************************************************
ok: [localhost] =>
default_ipv4:
master: 192.168.1.242
replica: 10.1.0.61
PLAY [all] ***********************************************************************************
TASK [setup] *********************************************************************************
ok: [master]
TASK [set_fact] ******************************************************************************
ok: [master]
TASK [debug] *********************************************************************************
ok: [master] =>
default_ipv4:
master: 192.168.1.242
replica: 10.1.0.61
PLAY [all] ***********************************************************************************
TASK [setup] *********************************************************************************
ok: [replica]
TASK [set_fact] ******************************************************************************
ok: [replica]
TASK [debug] *********************************************************************************
ok: [replica] =>
default_ipv4:
master: 192.168.1.242
replica: 10.1.0.61
PLAY RECAP ***********************************************************************************
localhost: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
master: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
replica: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Then, the creation of the XML file is trivial. The task
- template:
src: nodes.xml.j2
dest: /tmp/nodes.xml
run_once: true
delegate_to: localhost
vars:
nodes: [master, replica]
and the template
shell> cat nodes.xml.j2
{% for host in nodes %}
<node>
<host>{{ default_ipv4[host] }}</host>
<port>7800</port>
</node>
{% endfor %}
give always the recent results for all hosts
shell> cat /tmp/nodes.xml
<node>
<host>192.168.1.242</host>
<port>7800</port>
</node>
<node>
<host>10.1.0.61</host>
<port>7800</port>
</node>