# Unusal behaviour with set\_fact and add\_host

**URL:** <https://forum.ansible.com/t/unusal-behaviour-with-set-fact-and-add-host/38763>\
**Category:** Ansible Project\
**Created:** [April 23, 2024, 8:03pm UTC](https://forum.ansible.com/t/unusal-behaviour-with-set-fact-and-add-host/38763 "2024-04-23T20:03:55Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![deewon](https://avatars.discourse-cdn.com/v4/letter/d/ecb155/32.png) [@deewon](https://forum.ansible.com/u/deewon)\
**Post date:** [April 23, 2024, 8:03pm UTC](https://forum.ansible.com/t/unusal-behaviour-with-set-fact-and-add-host/38763/1 "2024-04-23T20:03:55Z")

</div>

ansible version: 2:11.2  
jinja version: 3.0.3  
python version: 3.6.8

Hello all

I have a peculiar problem with a relatively simple playbook I have written. It basically checks 2 servers to determine which one has more than 1 IP and uses that to set a simp;e fact called “is\_leader” for each node.

This fact is then to be used to build an in-memory inventory using module add\_host to iterate through the servers based on the value of that fact. See below:

- name: Get Server Recycling Order  
hosts: “{{ my\_servers | default (‘localhost’) }}”  
become: yes  
become\_method: sudo  
become\_user: root

tasks:

- name: Set Patching Sequence  
tags: always  
block:

- name: Get IP addresses of eth0 using nmcli command  
command: nmcli -g ip4.address conn show “System eth0”  
register: nmcli\_output  
changed\_when: false

- name: Get nmcli output  
debug:  
var: nmcli\_output

- name: Set is\_leader variable based on number of IPs  
set\_fact:  
is\_leader: “{{ (nmcli\_output.stdout.split(‘|’) | length) \> 1 }}”

- name: Display if server is ACTIVE (1) or PASSIVE (0)  
debug:  
var: is\_leader

- name: Debug is\_leader value  
debug:  
msg: “is\_leader value for {{ inventory\_hostname }} is {{ is\_leader }}”

- name: Add standby host  
add\_host:  
name: “{{ inventory\_hostname }}”  
groups: nodes  
when: not is\_leader

- name: Add primary host  
add\_host:  
name: “{{ inventory\_hostname }}”  
groups: nodes  
when: is\_leader

#- name: Execute tasks on servers in a specified order

# hosts: nodes

# gather\_facts: no

# serial: 1

# tasks:

# - name: Run a command in a specified order

# command: echo “Running on {{ inventory\_hostname }}”

# tags: always

The problem is that when this runs, the “is\_leader” fact is ignored for when the condition is false and the standby node is not added to the inventory. The relevant extract from the execution is below:

TASK [Set is\_leader variable based on number of IPs] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Tuesday 23 April 2024 19:46:31 +0000 (0:00:00.079) 0:00:16.815 \*\*\*\*\*\*\*\*\*  
ok: [node-1] =\> {  
“ansible\_facts”: {  
“is\_leader”: true  
},  
“changed”: false  
}  
ok: [node-2] =\> {  
“ansible\_facts”: {  
“is\_leader”: false  
},  
“changed”: false  
}

TASK [Display if server is ACTIVE (1) or PASSIVE (0)] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Tuesday 23 April 2024 19:46:31 +0000 (0:00:00.083) 0:00:16.898 \*\*\*\*\*\*\*\*\*  
ok: [node-1] =\> {  
“is\_leader”: true  
}  
ok: [node-2] =\> {  
“is\_leader”: false  
}

TASK [Debug is\_leader value] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Tuesday 23 April 2024 19:46:31 +0000 (0:00:00.072) 0:00:16.971 \*\*\*\*\*\*\*\*\*  
ok: [node-1] =\> {}

MSG:

is\_leader value for node-1 is True  
ok: [node-2] =\> {}

MSG:

is\_leader value for node-2 is False

TASK [Re-confirm is\_leader before adding to group] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Tuesday 23 April 2024 19:46:31 +0000 (0:00:00.074) 0:00:17.045 \*\*\*\*\*\*\*\*\*  
skipping: [node-1] =\> {}  
ok: [node-2] =\> {}

MSG:

Preparing to add node-2 to stby group based on is\_leader = False

TASK [Add standby proxysql node] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Tuesday 23 April 2024 19:46:31 +0000 (0:00:00.088) 0:00:17.134 \*\*\*\*\*\*\*\*\*  
skipping: [node-1] =\> {  
“changed”: false,  
“skip\_reason”: “Conditional result was False”  
}

TASK [Re-confirm is\_leader before adding to group] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Tuesday 23 April 2024 19:46:31 +0000 (0:00:00.036) 0:00:17.170 \*\*\*\*\*\*\*\*\*  
ok: [node-1] =\> {}

MSG:

Preparing to add node-1 to prim group based on is\_leader = True  
skipping: [node-2] =\> {}

TASK [Add primary proxysql node] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Tuesday 23 April 2024 19:46:31 +0000 (0:00:00.059) 0:00:17.230 \*\*\*\*\*\*\*\*\*  
changed: [node-1] =\> {  
“add\_host”: {  
“groups”: [  
“nodes\_prim”  
],  
“host\_name”: “node-1”,  
“host\_vars”: {}  
},  
“changed”: true  
}

PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0  
node-1 : ok=8 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0  
node-2 : ok=7 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

I’m not sure what I’m missing regarding this behaviour as it seems like it should simply work?

Thanks

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [April 23, 2024, 9:40pm UTC](https://forum.ansible.com/t/unusal-behaviour-with-set-fact-and-add-host/38763/2 "2024-04-23T21:40:49Z")

</div>

Hard to say. The job log you show doesn’t match the tasks in the playbook you posted. They seem to be the same down to the “Debug is\_leader value” task, but after that the task names in the log don’t match those in the playbook.

In the playbook you posted, task “Add standby host” an task “Add primary host” both add the hosts to the same group. That may be a source of your problem. But as we don’t see the output for those tasks …, hmm.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [April 23, 2024, 10:28pm UTC](https://forum.ansible.com/t/unusal-behaviour-with-set-fact-and-add-host/38763/3 "2024-04-23T22:28:40Z")

</div>

All that said, I don’t see why this one task wouldn’t work for your purposes:

```auto
    - name: Add hosts to groups
      ansible.builtin.add_host:
        name: "{{ inventory_hostname }}"
        groups:
          - nodes
          - "{{ 'nodes_prim' if is_active | d(false) else 'nodes_stby' }}"

```

---

<div class="post-metadata">

**Author:** ![deewon](https://avatars.discourse-cdn.com/v4/letter/d/ecb155/32.png) [@deewon](https://forum.ansible.com/u/deewon)\
**Post date:** [April 25, 2024, 12:38pm UTC](https://forum.ansible.com/t/unusal-behaviour-with-set-fact-and-add-host/38763/4 "2024-04-25T12:38:38Z")

</div>

Testing if my email is still deleted without any code

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [April 25, 2024, 7:30pm UTC](https://forum.ansible.com/t/unusal-behaviour-with-set-fact-and-add-host/38763/5 "2024-04-25T19:30:57Z")

</div>

I’ve been staring at this for quite a while. I was able to reproduce your issue, and I now understand what’s going on.

Rather than trying to duplicate the “single vs. multiple ips on an interface”, I just ran a playbook against two hosts (tango and cloister), and did

```auto
    - name: Set is_leader for tango and cloister
      ansible.builtin.set_fact:
        is_leader: '{{ true if inventory_hostname == "tango" else false }}'

```

After that, I could play with ansible.builtin.add\_host. And that’s where the confusion starts. Everything works “as expected” except for theses `add_host` tasks. So I went back and read the document on `add_host` very closely. I had not appreciated this bit about the [bypass\_host\_loop property](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/add_host_module.html#attribute-bypass_host_loop):

> **Forces a ‘global’ task** that **does not execute per host** , this **bypasses per host templating and serial, throttle and other loop considerations**
> 
> Conditionals will work **as if `run_once` is being used** , variables used will be from the **first available host**
> 
> This action will not work normally outside of lockstep strategies

So you can’t run `ansible.builtin.add_host` on all your hosts the same way you would, well, almost everything else. **If you want to loop over all your hosts** (which is the default behavior for most other modules), **then you have to do it explicitly** , like this:

```auto
    - name: Display is_leader for all hosts
      ansible.builtin.debug:
        var: is_leader

    - name: Show groups BEFORE add_host
      ansible.builtin.debug:
        msg: "{{ groups }}"

    - name: Add hosts to either the nodes_prim or nodes_stby group
      **ansible.builtin.add_host** :
        name: " **{{ item }}**"
        groups:
          - "{{ 'nodes_prim' if **hostvars[item].is_leader** else 'notes_stby' }}"
      **loop: "{{ ansible_play_hosts }}"**

    - name: Show groups AFTER add_host
      ansible.builtin.debug:
        msg: "{{ groups }}"

```
