39

Let's say a have a host that collects some data and it's in a group [collectors]. I also have hosts in group [reporters]. So I want to set a variable on reporters from groups['collectors'][0] ip address. But the playbook for setting up reporters doesn't run on [collectors] group so facts for this host are not collected. Is there a way not to hardcode the ip address?

76

You can access pretty much any inventory facts/variables by doing something like this:

{{ hostvars['foo.example.com']['ansible_eth0']['ipv4']['address'] }}

or, if you want to do it via an index into a group:

{{ hostvars[groups['collectors'][0]]['ansible_eth0']['ipv4']['address'] }}

The big trick is that you need to collect the facts for all the hosts/groups you're interested in. So you would want to modify your playbook that runs against the reporters group to include a no-op (dummy) task that is applied to the collectors group. That will cause Ansible to collect facts about the collectors hosts so that they can be accessed from the reporters group. So you might want to add something like this to the top of your reporters playbook:

- hosts: collectors
  name: Gather facts from collectors
  tasks: [ ]

The empty brackets basically mean that no tasks will be executed, but this will still force Ansible to gather facts about the collectors so that you can then reference them in the tasks that you run against your reporters.

Edit #1

It occurred to me that I should also mention that as of version 1.8 of Ansible, there is a fact-caching feature that is now available. Fact caching relies on a redis server to store facts between playbook runs. With it enabled, one playbook can reference facts that were obtained by another playbook that was run previously. The example the Ansible documentation gives:

Imagine, for instance, a very large infrastructure with thousands of hosts. Fact caching could be configured to run nightly, but configuration of a small set of servers could run ad-hoc or periodically throughout the day. With fact-caching enabled, it would not be necessary to “hit” all servers to reference variables and information about them.

  • 1
    Is there a way to set associative index as a variable? in example ansible localhost --extra-vars "metamorphosis_ip=172.16.3.73" -a "echo {{ hostvars[{{ metamorphosis_ip }}]['inv_domain'] }} " – corretge May 2 '16 at 16:26
  • To add to the answer above above make sure that you reference the Ansible FAQ here: docs.ansible.com/ansible/faq.html which explains things in detail, like looping over a group of hosts or setting a variable to get an specific host in a group. – einarc Jun 2 '16 at 5:22
  • You are the man!!! – dsutherland Dec 21 '17 at 17:57
  • Thank you for the idea of fetching facts from a node with an empty task list. – pedz Aug 24 '18 at 22:18

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.