Believable: a kind of list comprehension?

Given this inventory:

[webservers] 10.0.0.51 private_ip='XXXX' 10.0.0.52 private_ip='YYYY' 10.0.0.53 private_ip='ZZZZ' 

How can I get a list of private ips web servers?

 webservers_private_ips: "{{ }}" # ['XXXX', 'YYYY', 'ZZZZ'] 

I know that groups['webservers'] will give me the list ['10.0.0.51', '10.0.0.52', '10.0.0.53'] , and I can get private_ip via:

 {{ hostvars[item]['private_ip'] }} with_items: groups['webservers'] 

But I would like to declare a variable in my var file directly and not have a task to register it. It would be nice to do something like the following:

 webservers_private_ips: "{{ hostvars[item]['private_ip'] }} for item in groups['webservers']" 
+8
source share
3 answers

You can use the "retrieve" filter to get the components of a composite data object:

  webservers_private_ips: "{{ groups['webservers']|map('extract', hostvars, 'private_ip')|list }}" 
+7
source

Starting with Ansible 2.2, you can use the json_query filter.

In your example, it looks like this:

 - debug: msg: "{{item}}" loop: "{{hostvars | json_query(query)}}" vars: query: "* | [?contains(group_names, 'webservers')].private_ip" 

"hostvars" is the hash of the host name (for example, 10.0.0.51) for the corresponding variables. Filters cannot be applied to hashes (see this answer ), so we need to get a list of hostvar objects using "*". The resulting hostvars list is filtered for hosts that are members of the web servers group. For all matching hashes, the request returns the value "private_ip".

Docs: http://docs.ansible.com/ansible/latest/playbooks_filters.html#json-query-filter

0
source

It depends on the context. if you want to private_ip over the private_ip variable in the task, you can do it like this:

 - hosts: all tasks: - name: Print private_ips debug: var={{ hostvars[item]['private_ip'] }} with_items: - "{{ groups['webservers'] }}" 

Please note that this will print the IP addresses 3 times, as they will run on each server, so depending on what you are trying to achieve, you need to install hosts: all on your external server or something else.

You can also do this in a Jinja2 file if you plan to generate some configuration file. Again, it all depends on what you are striving for.

Please note that you can access IP information in facts collected automatically by:

 $ ansible someserver -m setup .... "ansible_eth1": { "active": true, "device": "eth1", "ipv4": { "address": "192.168.252.6", "netmask": "255.255.255.255", "network": "192.168.252.6" }, "mtu": 1500, "promisc": false }, .... 

which may also be more appropriate, depending on what you are trying to do.

Good luck.

-3
source

Source: https://habr.com/ru/post/977038/


All Articles