Ansible - get variables from group_vars and host_vars together into a list

Serge Hartmann picture Serge Hartmann · Jun 7, 2017 · Viewed 14.4k times · Source

I am trying to get from an inventory group a list of IP addresses instead of host names. These IP addresses are already in my hostvars but I cant make them matching a list from their group name.

Here is my original playbook :

- name: Install Kafka
  hosts: kafka
  roles: 
    - role: kafka
      kafka_hosts: "{{ groups['kafka'] | list }}"
      kafka_zookeeper_hosts: "{{ groups['zookeeper'] | list }}"

As you can see, kafka_hosts and kafka_zookeeper_hosts are lists. The result of this playbook to my servers configuration is correct :

/etc/kafka/consumer.properties:zookeeper.connect=opo-4:2181,opo-5:2181,opo-6:2181
/etc/kafka/producer.properties:metadata.broker.list=opo-1:9092,opo-2:9092,opo-3:9092

Unfortunately, this configuration does not work for all my servers because of DNS issues. I need a list of IP addresses instead of hostnames.

If I set manually the IP addresses in my playbook, my configuration works, unfortunately not dynamically :

  kafka_hosts: 
    - 192.168.48.1
    - 192.168.48.2
    - 192.168.48.3
  kafka_zookeeper_hosts: 
    - 192.168.48.4
    - 192.168.48.5
    - 192.168.48.6

And the result on my servers make it working :

/etc/kafka/consumer.properties:zookeeper.connect=192.168.48.4:2181,192.168.48.5:2181,192.168.48.6:2181
/etc/kafka/producer.properties:metadata.broker.list=192.168.48.1:9092,192.168.48.2:9092,192.168.48.3:9092

In this configuration I have to maintain manually my groups and my playbook with the same information. So I would like to get the hostvars from groups kafka and zookeeper.

Here are hostvars and groups, defined in the main inventory file :

[opo]
opo-1 ansible_host=192.168.48.1
opo-2 ansible_host=192.168.48.2
...
opo-6 ansible_host=192.168.48.6

[zookeeper]
opo-1
opo-2
opo-3

[kafka]
opo-4
opo-5
opo-6

What I have tried - based on answers found on stackoverflow from similar issues :

  • kafka_hosts: "{{ groups[['kafka']['ansible_host']] | list }}"
  • kafka_hosts: "{{ [hostvars[groups['kafka'][0]]['ansible_host']] | list }}" # the list contains only the first ip address
  • kafka_hosts: "{{ [hostvars[groups['kafka']]['ansible_host']] | list }}"
  • kafka_hosts: "{{ hostvars[groups['kafka']].ansible_host | list }}"
  • kafka_hosts: "{{ [hostvars.[groups['kafka']].ansible_host] | list }}"
  • kafka_hosts: "{{ groups['kafka'].ansible_host | list }}"

None of them gives the expected list of IP addresses.

Answer

Konstantin Suvorov picture Konstantin Suvorov · Jun 7, 2017

You need to use extract and map combination:

kafka_hosts: "{{ groups['kafka'] | map('extract',hostvars,'ansible_host') | list }}"