Определение

Начнем с того, что переменная, полученная при помощи set_fact, будет существовать вплоть до завершения плейбука Из этого получаем — эта переменная остается “закрепленной” за хостом или группой хостов на котором/которых она была получена

Способ №1: Обращение к факту напрямую

Для примера показал, что можно записать в отдельную переменную, либо использовать напрямую (fact_1 и 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'] }}"

Способ №2: Использовать группу all и run_once: true

В первой таске мы используем параметр run_once: true для того, чтобы выполнить первую таску единожды и далее мы уже выполняем таску на всех хостах, которая запишет значение для каждого из хостов (если просто генерировать на каждом хосте отдельно, то у каждого из них будет случайное значение)

- 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 }}"

Способ №3: Использовать delegate_to

Важно использовать delegate_facts: true, поскольку при при смене хоста через delegate_to переменная inventory_hostname сохраняется и, следовательно, все факты будут присвоены изначальному хосту (в примере этот хост — localhost)

localhost не входит в группу all, а потому если вам понабодится определить факт и на нем, то нужно объединить списки хостов (например, "{{ 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