Delgate_facts understanding

Hello everyone,

I don’t totally get the point of the delegate_facts usage in Ansible.

I have written the follow code to test this clause:

- name: delegate facts testing
hosts: localhost
tasks:

- name: print FQDN - first attempt
debug:
msg: “{{ ansible_fqdn }}”

- name: gather facts on remote host
setup:
delegate_to: “{{ item }}”
with_items: “{{ groups[‘anotherhost’] }}”
delegate_facts: false

- name: print ansible FQDN - second attempt
debug:
msg: “{{ ansible_fqdn }}”

So… If I set DELEGATE_FACTS to false, I get the following output:

→ PRINT FQDN - First attempt → LOCAL HOSTNAME
→ PRINT FQDFN - Second attempt → ANOTHER HOSTNAME

  • Is this because the default facts gathered at the beginning of the play (via setup localhost) , have been overwritten by the facts gathered on the ANOTHERHOST?

Otherwise, If I change delegate_facts to true. I obtain LOCALHOSTNAME in both attempts.

  • Is this because I ve assigned the default gathered facts to anotherhost’s facts?

Sorry for this silly question… but I cannot find an example good enough to understand this.

Thank you all in advance :slight_smile:
Vicente.

*- name: delegate facts testing*
* hosts: localhost
* tasks:
* - name: print FQDN - first attempt
* debug:
* msg: "{{ ansible_fqdn }}"
* - name: gather facts on remote host
* setup:
* delegate_to: "{{ item }}"
* with_items: "{{ groups['anotherhost'] }}"
* delegate_facts: false
* - name: print ansible FQDN - second attempt
* debug:
* msg: "{{ ansible_fqdn }}"

   If I set DELEGATE_FACTS to false, I get the following output:
     --> PRINT FQDN - First attempt --> LOCAL HOSTNAME
     --> PRINT FQDFN - Second attempt --> ANOTHER HOSTNAME

   Is this because the default facts gathered at the beginning of the
   play (via setup localhost) , have been overwritten by the facts gathered on
   the ANOTHERHOST?

     YES.

   Otherwise, If I change delegate_facts to true. I obtain LOCALHOSTNAME in
   both attempts.

   Is this because I ve assigned the default gathered facts to
   anotherhost's facts?

     YES.

For the reference: "The directive delegate_facts may be set to True to assign
the task’s gathered facts to the delegated host instead of the current one."
https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html#delegated-facts

Cheers,

  -vlado

Thank you very much Vlado.

But it means that you have to manage this clause carefully, because if you use delegate_facts = FALSE (true by default) , the rest of your tasks after the delegated one will be using {{ ansible_fqdn }} with a wrong hostname (different from the current managed host), which could lead to errors… =S

I don’t get the point of this functionality at all, any useful example that you have in mind?

Thank you for your help :slight_smile:

>
> > *- name: delegate facts testing*
> > * hosts: localhost
> > * tasks:
> > * - name: print FQDN - first attempt
> > * debug:
> > * msg: "{{ ansible_fqdn }}"
> > * - name: gather facts on remote host
> > * setup:
> > * delegate_to: "{{ item }}"
> > * with_items: "{{ groups['anotherhost'] }}"
> > * delegate_facts: false
> > * - name: print ansible FQDN - second attempt
> > * debug:
> > * msg: "{{ ansible_fqdn }}"
> >
> > If I set DELEGATE_FACTS to false, I get the following output:
> > --> PRINT FQDN - First attempt --> LOCAL HOSTNAME
> > --> PRINT FQDFN - Second attempt --> ANOTHER HOSTNAME
> >
> > Is this because the default facts gathered at the beginning of the
> > play (via setup localhost) , have been overwritten by the facts
> > gathered on
> > the ANOTHERHOST?
>
> YES.
>
> > Otherwise, If I change delegate_facts to true. I obtain LOCALHOSTNAME
> > in
> > both attempts.
> >
> > Is this because I ve assigned the default gathered facts to
> > anotherhost's facts?
>
> YES.
>
>
> For the reference: "The directive delegate_facts may be set to True to
> assign
> the task’s gathered facts to the delegated host instead of the current
> one."
>
> https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html#delegated-facts

But it means that you have to manage this clause carefully, because if you
use delegate_facts = FALSE (true by default) , the rest of your tasks
after the delegated one will be using {{ ansible_fqdn }} with a wrong
hostname (different from the current managed host), which could lead to
errors... =S

  YES. (... if you use "delegate_facts: false" (false by default) ...)

  To avoid the problem use "delegate_facts: true" with the "setup" module.

I don't get the point of this functionality at all, any useful example that
you have in mind?

  The example in the doc is a good use-case
  https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html#delegated-facts

  - hosts: app_servers
    tasks:
      - name: gather facts from db servers
        setup:
        delegate_to: "{{item}}"
        delegate_facts: True
        loop: "{{groups['dbservers']}}"

  The play is running at app_servers and knows nothing about the dbservers.
  The task will "setup" dbservers facts that can be used by app_servers.

Cheers,

  -vlado

Hello,

Are we sure that the delegate_facts is set to “false” by default? As stated in the doc:

“By default, any fact gathered by a delegated task are assigned to the (the current host) instead of the host which actually produced the facts (the delegated to host)”

If the facts gathered by a delegated task are assigned to inventory_hostame (CURRENT HOST), means that the delegate_facts = true, isn’t it?
As per my first code example, if you use delegate_facts = false, you will have the delegated hosts’s facts instead of inventory_hostnames’s (which are overridden). In the case of delegate_facts = true, you will keep CURRENT inventory_hostname’s facts along the whole play.

Thank you very much, sorry for bothering with this :slight_smile:

By the way, your example makes sense… if you want to use DB Servers facts in APPServers tasks.

Thanks a lot,
Vicente.

Are we sure that the delegate_facts is set to "false" by default?

  (I wonder how "we" can be sure? Kind of a collective experience?)

  The default can be easily tested. For example the play

  - hosts: test_01
    tasks:
      - setup:
        delegate_to: test_02
        delegate_facts: true
      - debug:
          var: ansible_hostname

  gives

  ok: [test_01] => {
    "ansible_hostname": "test_01"
  }

  The same play without the line "delegate_facts: true" gives

  ok: [test_01] => {
    "ansible_hostname": "test_02"
  }

By the way, your example makes sense.. if you want to use DB Servers facts
in APPServers tasks.

  It's not my example. It's been publicly available for a while.

Great!
So I can say that the wording of the doc is not totally accurate…

MENTAL NOTE: If it’s false by default, just take care and don’t forget to use delegate_facts = true (setup module) if you don’t want to override the facts.

Regarding “your example” I meant that It was suggested by you to check :slight_smile:

Thank you very much Vlado, hope it helps for my certification exam this week!

Cheers.

No. The wording is OK.
  https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html#delegated-facts

  Short story

I understand this the other way around:

Short story

Ok,
There’s several things going on here:
(1) The wording in the doc isn’t great and it isn’t grammatically “correct” either, so it is not “OK”;
(2) The wording in the doc is accurate relative the originally intended function of the “delegate_facts” switch;
(3) The metaphor “delegate_facts” isn’t very helpful in understanding what is actually going on—as facts aren’t what is being delegated, but it is in fact the custody of them that is.

Item #3 on my list is clearly (to a native speaker / writer of English) indicated in the paragraph following the example code on the documentation page. Setting the “delegate_facts” switch to true means that not only are the shorthand host vars (EG: “ansible_hostname”) of the original target host PRESERVED in the environment running on the delegate target host, but it also means that facts gathered on the delegate host end up IN THE CUSTODY OF the original target host (or host group) that will be running the play. This is done without overriding the shorthand host vars, as to do so would, within the constraining metaphor of Ansible, be without any intended meaning.

Vincente,
Does that explanation help?

Vlado,
Do you want to proof a quick fix to the grammar & wording of the doc page (before or after I post a PR)?

Sure. Post it here. Others might be interested too.

  Thank you,

  -vlado

Thank you both! Eveything clear now :slight_smile:

By the way, what does “PR” mean?

It is "Pull Request".
https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests

No PR by Benjamin yet
https://github.com/ansible/ansible/pulls

Cheers,

  -vlado

It is "Pull Request".
https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests

No PR by Drew yet
https://github.com/ansible/ansible/pulls

Cheers,

  -vlado