Build fact dynamically based on variables of other hosts
I am creating a role in Ansible to let mongodb cluster with other machines. I am using the mongodb_replicaset collection for this use case.
I want to build the member list of the cluster with Ansible.
Imagine there are 7 hosts in the play. The variables are set like this:
host-1 # secondary
host-2 # secondary
host-3 # secondary
host-4 # primary
host-5 # arbiter
host-6 # arbiter
host-7 # secondary
How can I configure Ansible so that it will build the members list based on the amount of hosts in the play, and set a priority based on the role. In this case, host-4 should contain the variable, because that is the primary and will eventually execute the task.
E.g. primary = 1, secondary = 0.5 and arbiter = 0.1
Desired output:
- host: host-1
priority: 0.5
- host: host-2
priority: 0.5
- host: host-3
priority: 0.5
- host: host-3
priority: 0.5
- host: host-4
priority: 1.0
- host: host-5
priority: 0.1
- host: host-6
priority: 0.1
- host: host-7
priority: 0.5
Define a dictionary with the weight:
member_weight:
primary: 1.0
secondary: 0.5
arbiter: 0.1
Then, given that your "type of member" is registered under a fact member_type
on the host, loop on the hosts in the play:
- set_fact:
members: >-
{{
members | default([]) +
[{
'host': item,
'priority': member_weight[hostvars[item].member_type]
}]
}}
loop: "{{ ansible_play_hosts }}"
vars:
member_weight:
primary: 1.0
secondary: 0.5
arbiter: 0.1
Given the inventory:
all:
children:
nodes:
hosts:
host-1:
member_type: secondary
host-2:
member_type: secondary
host-3:
member_type: secondary
host-4:
member_type: primary
host-5:
member_type: arbiter
host-6:
member_type: arbiter
host-7:
member_type: secondary
And the playbook:
- hosts: nodes
gather_facts: no
tasks:
- set_fact:
members: >-
{{
members | default([]) +
[{
'host': item,
'priority': member_weight[hostvars[item].member_type]
}]
}}
loop: "{{ ansible_play_hosts }}"
run_once: true
vars:
member_weight:
primary: 1.0
secondary: 0.5
arbiter: 0.1
- debug:
var: members
run_once: true
This yields:
TASK [set_fact] ***************************************************************
ok: [host-1] => (item=host-1)
ok: [host-1] => (item=host-2)
ok: [host-1] => (item=host-3)
ok: [host-1] => (item=host-4)
ok: [host-1] => (item=host-5)
ok: [host-1] => (item=host-6)
ok: [host-1] => (item=host-7)
TASK [debug] ******************************************************************
ok: [host-1] =>
members:
- host: host-1
priority: 0.5
- host: host-2
priority: 0.5
- host: host-3
priority: 0.5
- host: host-4
priority: 1.0
- host: host-5
priority: 0.1
- host: host-6
priority: 0.1
- host: host-7
priority: 0.5