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