Search code examples
ansibleansible-inventory

Get IP address from hosts in a Group


I have a simple playbook referencing an inventory hosts.yml file. I want to be able to query a group, and retrieve the IP address for hosts in that group.

Simple hosts.yml

---
all:
  hosts:
    w2k16-std:
      ansible_host: 10.1.1.12
      in_play_ip: 10.200.2.12
    w2k12-x64:
      ansible_host: 10.1.1.13
      in_play_ip: 10.200.2.13
    lin-test:
      ansible_host: 10.1.1.20
      in_play_ip: 10.200.2.20
  children:
    windows:
      vars:
        ansible_connection: winrm
        ansible_winrm_transport: certificate
        ansible_winrm_cert_pem: /home/user/.ssh/windows.pem
        ansible_winrm_cert_key_pem: /home/user/.ssh/windows_key.pem
        ansible_port: 5986
        ansible_winrm_scheme: https
        ansible_winrm_server_cert_validation: ignore
      hosts:
        w2k12-x64:
        w2k16-std:
    linux:
      hosts:
        lin-test:
    targets:
      hosts:
        w2k12-x64:
        w2k16-std:

Here's the simple playbook:

---
- hosts: kali
  vars:
  tasks:
    - name: Create comma delimited list of target names from targets group.
      set_fact:
        targets: "{{ groups.targets | list | join(',') }}"

    - name: List targets from Inventory
      debug:
        var: targets

Produces the following output:

TASK [List targets from Inventory] ***************************************
ok: [lin-test] => {
    "targets": "w2k12-x64,w2k16-std"

I want be able do the following:

  • Retrieve the members of the targets group (w2k12-x64 & w2k16-std)
  • Get the IP address listed in ansible_host values.
  • Create a comma delimited list of the target's IPs (10.1.1.12,10.1.1.13).

So far I can:

  • Retrieve the members of the targets group (w2k12-x64 & w2k16-std)
  • Create a comma delimited list of the target names.

I'm not sure if my hosts file is correctly laid out, or if I just need help with the query?

Desired output:

Produce the following output:

TASK [List target IPs from Inventory] ***************************************
ok: [lin-test] => {
    "targets": "10.1.1.12,10.1.1.13"

Solution

  • You can extract the value you are looking for from the hostvars special variable.

    You can also filter the items of the dictionary hostvars contained in the group targets thanks to the filters dict2items, which will create a key/value list from the dictionary, and selectattr to get only the items of the created list having a key matching in the targets group.

    Then, you just need to reduce the list of dictionaries to a simple list via map, because you are only interested in the ansible_host attribute, and join the whole thing together.

    So, this end up with this single task:

    - debug:
        msg: >-
          {{
            hostvars 
              | dict2items 
              | selectattr('key', 'in', groups.targets)
              | map(attribute="value.ansible_host")
              | join(',')
          }}
    

    Which yields your expected:

    TASK [debug] **************************************************************
    ok: [localhost] => 
      msg: 10.1.1.12,10.1.1.13