In general, this use case might be solved in three steps. Create, share, and use the variables. For example, given the inventory
shell> cat hosts
host1
host2
the playbook works as expected
- name: Run single host and create facts
hosts: host1
tasks:
- set_fact:
fact1: foo
- name: Share facts among all hosts
hosts: all
tasks:
- set_fact:
fact1: "{{ hostvars.host1.fact1 }}"
run_once: true
- name: Use shared facts
hosts: host2
tasks:
- debug:
var: fact1
If you extend the use case to "passing facts from a group of hosts to another group of hosts" the problem is how to efficiently share the variables? Create a playbook dynamically. For example, given the inventory
shell> cat hosts
host1
host2
host3
host4
let host1 and host4 create the variables and host2 and host3 use them. Create the template
shell> cat share-vars.yml.j2
- name: Share facts among all hosts
hosts: all
tasks:
- set_fact:
{% for i in share_vars %}
{{ i.var }}: "{{ lbr }} hostvars.{{ i.host }}.{{ i.var }} {{ rbr }}"
{% endfor %}
run_once: true
and the playbook
shell> cat create-share-vars.yml
- name: Create playbook share-vars.yml
hosts: localhost
vars:
share_vars:
- {host: host1, var: fact1}
- {host: host4, var: fact4}
lbr: "{{ '{{' }}"
rbr: "{{ '}}' }}"
tasks:
- template:
src: share-vars.yml.j2
dest: share-vars.yml
gives
shell> cat share-vars.yml
- name: Share facts among all hosts
hosts: all
tasks:
- set_fact:
fact1: "{{ hostvars.host1.fact1 }}"
fact4: "{{ hostvars.host4.fact4 }}"
run_once: true
Import this playbook, for example
shell> cat playbook.yml
- hosts: host1
tasks:
- set_fact:
fact1: foo
- hosts: host4
tasks:
- set_fact:
fact4: bar
- import_playbook: share-vars.yml
- hosts: host2,host3
tasks:
- debug:
var: fact1
- debug:
var: fact4
gives (abridged)
PLAY [host2,host3] *********************************************************
TASK [debug] ***************************************************************
ok: [host2] =>
fact1: foo
ok: [host3] =>
fact1: foo
TASK [debug] ***************************************************************
ok: [host2] =>
fact4: bar
ok: [host3] =>
fact4: bar
Notes
- What is the advantage of the template? Change the variable share_vars and rebuild the imported play when needed. Don't change the code.
- In Ansible, it's not possible to substitute the left-hand side of an assignment, i.e. no symbolic reference.
- Put "gather_facts: false" to the plays if you don't need it.