Search code examples
ansibleansible-inventory

How can I resolve an inventory member who has a certain attribute?


I need to pass a specific host from my inventory as a parameter into a role. The host is part of a group but is demarcated by a variable that none of the other hosts have.

snippet of: hosts.yml

  dbservers:
       hosts:
        pg01:
         ansible_host: pg01.domain.com
         master_slave: master
        pg02:
         ansible_host: pg02.domain.com
         master_slave: slave

I want to be able to resolve pg01 based on the fact that the variable master_slave is set to 'master' such that I can call into a role like this:

      - name: Do something
        include_role:
         name: a.database.role.to.run.on.master
        vars:
          master_database_host: {{ something that resolves to pg01 }}

How can I resolve the appropriate host from inventory?


Solution

  • You can use a mix of filters to extract the host you need:

    tasks:
    - debug:
        msg: '{{groups["group_name"] | map("extract", hostvars) | selectattr("master_slave", "equalto", "master") | map(attribute="inventory_hostname") | list}}'
    

    Step by step:

    groups["group_name"] is a list of all the hosts in the group group_name.

    map("extract", hostvars) takes hostvars, a dictionary mapping the host to their variables, and extracts the hosts that are in group_name (i.e. groups["group_name"]). This results in a list containing the hosts in group_name mapped to their variables.

    selectattr("master_slave", "equalto", "master") selects all hosts who have an attribute master_slave that equals to master. This result in a list with all the hosts that are masters mapped to their variables.

    map(attribute="inventory_hostname") takes a list as input and returns the inventory_hostname attribute of every item. This result in a list with all the hosts that are masters.