conedmiro
conedmiro

Reputation: 103

Trying to set global Ansible fact based on ansible_local fact

I am trying to utilize a local Ansible fact located on 1 of 3 DB hosts to set a global fact so that the other nodes can utilize the IP.

3 nodes, 3 sets of local facts, setting ansible_local.edb.type to either:

Node2 has ansible_local.edb.type == standby, and I'm trying to set_fact globally to the IP address. My issue is that to conditionally set a fact, then when has to be :

when: ansible_local.edb.type == "standby"

But that is only setting the fact on the specific node, obviously due to the conditional

I tried blocking a task within a block to get the piped output, but seemed to break the syntax -- this would be a really cool addition to Ansible if it were possible.

- debug:
    msg: "{{ ansible_local.edb.type }}"

- name: Set DB standby IP address fact
  set_fact:
    db_standby_node_ip: "{{ hostvars[inventory_hostname][prod_nic]['ipv4']['address'] }}"
  when: ansible_local.edb.type == "standby"

- debug:
    msg: "{{ db_standby_node_ip }}"



TASK [debug] 
*******************************************************************
task path: /path/to/playbook.yml
ok: [Node1] => {
    "msg": "master"
}
ok: [Node2] => {
    "msg": "standby"
}
ok: [Node3] => {
    "msg": "witness"
}

TASK [Set DB standby IP address fact] 
******************************************
task path: /path/to/playbook.yml
ok: [Node2] => {
    "ansible_facts": {
        "db_standby_node_ip": "x.x.x.y"
    },
    "changed": false,
    "invocation": {
        "module_args": {
            "db_standby_node_ip": "x.x.x.y"
        },
        "module_name": "set_fact"
    }
}

TASK [debug]
*******************************************************************
task path: /path/to/playbook.yml
fatal: [Node1]: FAILED! => {
    "failed": true,
    "msg": "the field 'args' has an invalid value,..
}
fatal: [Node3]: FAILED! => {
    "failed": true,
    "msg": "the field 'args' has an invalid value,...
}
ok: [Node2] => {
    "msg": "x.x.x.y"
}

I was hoping someone might have a different outlook on how to get the fact to be set globally, but based on a local fact?

Upvotes: 0

Views: 506

Answers (1)

Konstantin Suvorov
Konstantin Suvorov

Reputation: 68329

Use json_query to fetch a host with standby == "true" as filter, there's no need to use inventory_hostname.

- name: Set DB standby IP address fact
  set_fact:
    db_standby_node_ip: {{ hostvars | json_query('* | [?ansible_local.edb.type==`standby`] | [0].'+prod_nic+'.ipv4.address') }}"

Upvotes: 0

Related Questions