Hi all,
I signed up specifically for this topic because I’m trying to wrap my head around this and there seems to be absolutely no solution for this other than duplicated code.
In this example i’m trying to find the correct IP to use in my main playbook, so that i may reference it using hostvars[‘logging01’].backnet_ip in a jinja templatefile to create a config file on zzz-test01 to push my logs to my logging server.
I wrote a role that sets a lot of facts special to our company and it has worked fine so far, as long as the host is part of the play. Now that I do not want to target logging01 with my play (Might also be that a playbook has “hosts: all” and I simply run it using --limit) I am running into problems with fact delegation.
What I’m trying to do is this:
- name: Test playbook for fact delegation
hosts: zzz-test01
gather_facts: false
vars:
ansible_user: root
tasks:
- name: Setup facts on host not part of this play
vars:
delegation_host: "logging01"
delegate_to: "{{ delegation_host }}"
delegate_facts: true
run_once: true
block:
- name: Run fact gathering on "{{ delegation_host }}"
setup:
- name: Run mde_common on "{{ delegation_host }}"
tags: always
import_role:
name: mde_common
Inside that role I have two problems, which are essentially the same:
- name: "Set variables according to environment: Pre-Live"
set_fact:
env: "prelive"
mde_host_prefix: "zzz-"
pretty_env: "Pre-Live"
regular_user: "test"
when: inventory_hostname is match("^zzz-.*")
- name: "Check for 10.0.0.0/24 IP and overwrite variables for office"
set_fact:
backnet_ip: "{{ ansible_facts['all_ipv4_addresses']
| select('search', '^10\\.0\\.0\\.')
| list
| sort
| first }}"
when: >
ansible_facts['all_ipv4_addresses']
is defined and
(
ansible_facts['all_ipv4_addresses']
| select('search', '^10\\.0\\.0\\.')
| list | length > 0
)
- inventory_hostname always targets the delegator, not the delegatee.
- As for using ansible_facts to set a fact, this does not work.
If this role is called using delegate_to: i’d need to do this:
- name: "Check for 10.0.0.0/24 IP and overwrite variables for office"
set_fact:
backnet_ip: "{{ hostvars[delegation_host]['ansible_facts']['all_ipv4_addresses']
| select('search', '^10\\.0\\.0\\.')
| list
| sort
| first }}"
when: >
hostvars[delegation_host]['ansible_facts']['all_ipv4_addresses']
is defined and
(
hostvars[delegation_host]['ansible_facts']['all_ipv4_addresses']
| select('search', '^10\\.0\\.0\\.')
| list | length > 0
)
Note, I’m doing:
hostvars[delegation_host]['ansible_facts']['all_ipv4_addresses']
because otherwise the name of the fact changes
hostvars[delegation_host]['ansible_all_ipv4_addresses']
Now I cannot do something like this:
- name: Determine effective ansible facts source
set_fact:
effective_ansible_facts: >-
{{
(delegation_host is defined)
| ternary(
hostvars[delegation_host]['ansible_facts'],
ansible_facts
)
}}
because that, again, puts that fact either in the hostvars of delegation_host, which I would need to reference by hostvars, or easily referencable if not called with delegation.
The only solution I can think of for a scenario like this is duplicating every single task and adding “when: delegation_host is not defined” […]
- name: "Check for 10.0.0.0/24 IP and overwrite variables for office"
set_fact:
backnet_ip: "{{ hostvars[delegation_host]['ansible_facts']['all_ipv4_addresses']
| select('search', '^10\\.0\\.0\\.')
| list
| sort
| first }}"
when: >
hostvars[delegation_host]['ansible_facts']['all_ipv4_addresses']
is defined and
(
hostvars[delegation_host]['ansible_facts']['all_ipv4_addresses']
| select('search', '^10\\.0\\.0\\.')
| list | length > 0
)
- name: "Check for 10.0.0.0/24 IP and overwrite variables for office"
set_fact:
backnet_ip: "{{ ansible_facts['all_ipv4_addresses']
| select('search', '^10\\.0\\.0\\.')
| list
| sort
| first }}"
when: >
ansible_facts['all_ipv4_addresses']
is defined and delegation_host is not defined and
(
ansible_facts['all_ipv4_addresses']
| select('search', '^10\\.0\\.0\\.')
| list | length > 0
)
[…] which I’d like to avoid for obvious reasons. The scenario I am thinking of cannot be that special to our use-case. Is there really no solution for this?
Sorry for rambling, but I want you to see that I have thought about this for hours now.
Thanks in advance for anyone taking the time to read this madness.
~nosebeggar