'How to get hostname with largest number in the inventory

How to extract a hostname with the largest number and use that hostname in the mount command as shown below? Basically, I have only one volume that needs to be mounted across all hosts in the group and the volume is created with the hostname with the largest number if that makes sense.

server1 
server2  
vol_server2 => need to be mounted on server1 and 2.

The mymount variable is set globally

The mymontvol var is set in the local role vars file

mymountvol: storage:/{{ inventory_hostname }}_dbfiles

Here is the mount task:

- name: mount volume
  mount:
    name: "{{ mymount }}"
    state: mounted
    fstype: nfs
    src: "{{ mymountvol }}"
    opts: rw,bg,hard,nointr,nolock,noatime
  when: mymount is defined and mymountvol is defined 
  become: true
  become_user: root


Solution 1:[1]

You could use regex to first select matching hosts from all existing hosts then extract the highest number.

  • Get all hosts can be done via the groups.all special variable
  • Selecting the matching hosts can be done with the select filter and the regex test: select('regex', '^' ~ server_prefix ~ '\d+$')
  • Getting only the numeric part can be done with map filter along with the regex_replace one: map('regex_replace', '^' ~ server_prefix ~ '(\d+)$', '\1')
  • You will need to convert those values of the list, still with a map, in int
  • There is a built-in max filter in Jinja

So, all this together give you the task:

- set_fact:
    selected_host: >-
      {{
        server_prefix ~ (
          groups.all
          | select('regex', '^' ~ server_prefix ~ '\d+$')
          | map('regex_replace', '^' ~ server_prefix ~ '(\d+)$', '\1')
          | map('int')
          | max
        )
      }}
  vars:
    server_prefix: server

Given the inventory:

all:
  hosts:
    server1:
    server2:
    server42:
    server101:

And those two tasks:

- set_fact:
    selected_host: >-
      {{
        server_prefix ~ (
          groups.all
          | select('regex', '^' ~ server_prefix ~ '\d+$')
          | map('regex_replace', '^' ~ server_prefix ~ '(\d+)$', '\1')
          | map('int')
          | max
        )
      }}
  vars:
    server_prefix: server

- debug:
    var: selected_host

This yields:

TASK [debug] ***************************************************************
ok: [localhost] => 
  selected_host: server101

Solution 2:[2]

For example, given the hosts

shell> cat hosts
server1
server2
server42
server101

declare the variables

max: "{{ groups.all|map('split', 'server')|map('last')|map('int')|max }}"
selected_host: "server{{ max }}"

give

selected_host: server101

Solution 3:[3]

Thanks for all your responses and appreciate it. I came up with something very simple by defining the variables in the role vars file e.g.

role/my_role/vars

superhost: "{{ (groups[group_names[0]] | sort)[-1] }}"
dbdir: path:/{{ superhost }}_dbdir

The dbdir variable is then used in the task below which works.

  - name: mount vol
    mount:
      name: "{{ source_files }}"
      state: mounted
      fstype: nfs
      src: "{{ dbdir }}"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 khasifrog