Managing Primary/Secondary relationship in cluster

I have a pair of servers (server1..domain, server2..domain) in two environments (staging and production). Server1 is primary, server2 is secondary.

When I originally built the playbook, I had aliases in the inventory file

[staging-cluster]
primary server1.staging.domain
secondary server2.staging.domain

And I’d target the IP of the other host with {{ hostvars[‘primary’][‘ansible_eth0’][‘ipv4’][‘address’] }} to get the of the “other” host. This worked fine, until I needed the playbook to target another set of hosts in production:

[production-cluster]
primary server1.prod.domain
secondary server2.prod.domain

The problem with the above, aliases are global and you can’t have more than one in an inventory. So…this breaks the above lookup {{ hostvars[‘secondary’][‘ansible_eth0’][‘ipv4’][‘address’] }}

As much as I disliked the idea, I then thought to leverage hostvars/serverX.environment.domain with a var like:

primary: true
partner: server2.environment.domain

The above var would exist on server1 since it is the primary and it’s partner is server2

The problem with the above is, I can’t expand {{ partner }} in the above fact (may not have explained that properly, I can’t do this:

{{ hostvars[‘{{ partner }}’][‘ansible_eth0’][‘ipv4’][‘address’] }} or this {{ hostavars[{{partner}}][‘ansible_eth0’][‘ipv4’][‘address’] }}

Anyone have any ideas on how I can manage a primary/secondary role/membership in a cluster? Actually defining if the host is primary/secondary is the easy part…but defining it’s partner and getting facts from its partner, I’m not certain of.

Thanks!!

If you wanted to get the ip address of the first node in the production-cluster, you could do something like this. Think of the group as a list and 0 being the first element in the list.

"{{ hostvars[groups['production-cluster'][0]]['ansible_eth0']['ipv4']['address'] }}"

as far as your second example goes, you have some syntax errors in defining your variable. You don’t need to encapsulate “partner” in curly brackets or quotes. The following should work:

{{ hostvars[partner]['ansible_eth0']['ipv4']['address'] }}

  • James

{{ hostvars[partner][‘ansible_eth0’][‘ipv4’][‘address’] }} << doesn’t work

“{‘msg’: “AnsibleUndefinedVariable: One or more undefined variables: ‘partner’ is undefined”, ‘failed’: True}”

in inventory/host_vars/server1.domain there is ‘partner: server2.domain’

That indicates you haven’t defined “partner” properly. Make sure it’s listed in the right pace in your inventory host_vars.

Ah, I didn’t see that last line. Do a:

  • debug: var=partner

Just to make sure you have your variables loading properly.

I had the remnants of the aliases so host_vars/server1 didn’t match ‘primary’

I’m not getting the var.

Thanks!

Another way is 'differenct'.
(see http://docs.ansible.com/playbooks_variables.html#set-theory-filters)

    - debug: msg="{{ (groups['pair'] | difference(inventory_hostname))[0] }}"

The result is list, not a value. So it requires [0] to get actual hostname.
It works if there are more hosts.