Definition

Let’s start with the fact that the variable obtained using set_fact will exist until the completion of the playbook From this we get - this variable remains “fixed” to the host or group of hosts on which it was obtained

Method №1: Getting fact directly

For example, I showed that you can write it into a separate variable, or use it directly (fact_1 and fact_2)

- name: Set fact on localhost
  hosts: localhost
  tasks:
    - name: Set fact
      ansible.builtin.set_fact:
        localhost_variable: Hello!

- hosts: debian-host
  vars:
    shared_variable: "{{ hostvars['localhost']['localhost_variable'] }}"
  tasks:
    - name: Show this variable
      ansible.builtin.debug:
        msg: "{{ shared_variable }}"

    - name: Set fact for this host
      ansible.builtin.set_fact:
        fact_1: "{{ shared_variable }}"
        fact_2: "{{ hostvars['localhost']['localhost_variable'] }}"

Method №2: Using group all and run_once: true

In the first task we use the parameter run_once: true to execute the first task only once and then we execute the task on all hosts, which will write the value for each of the hosts (if we simply generate on each host separately, then each of them will have a random value)

- name: Play this on all hosts
  hosts: all
  tasks:
    - name: Generate password and token
      ansible.builtin.set_fact:
        _password: "{{ lookup('ansible.builtin.password', '/dev/null', chars=['ascii_letters', 'digits'], length=10) }}"
        _token: "{{ lookup('community.general.random_string', length=32) }}"
      run_once: true

    - name: Make these values shared
      ansible.builtin.set_fact:
        password: "{{ _some_password }}"
        token: "{{ _some_token }}"

Method №3: Using delegate_to

It is important to use delegate_facts: true because when changing the host via delegate_to, the inventory_hostname variable is preserved and therefore all facts will be assigned to the original host (in the example, this host is localhost)

localhost is not in the all group, so if you need to determine the fact on it, you need to combine the host lists (for example, "{{ groups['all'] + ['localhost'] }}"):

- name: Play this locally
  hosts: localhost
  tasks:
    - name: Generate password and token
      ansible.builtin.set_fact:
        _password: "{{ lookup('ansible.builtin.password', '/dev/null', chars=['ascii_letters', 'digits'], length=10) }}"
        _token: "{{ lookup('community.general.random_string', length=32) }}"

    - name: Make these values shared
      ansible.builtin.set_fact:
        password: "{{ lookup('ansible.builtin.password', '/dev/null', chars=['ascii_letters', 'digits'], length=10) }}"
        token: "{{ lookup('community.general.random_string', length=32) }}"
      loop: "{{ groups['all'] + ['localhost'] }}"
      delegate_to: "{{ item }}"
      delegate_facts: true