# Here's how to access facts from other hosts (advanced feature)

**URL:** <https://forum.ansible.com/t/heres-how-to-access-facts-from-other-hosts-advanced-feature/11430>\
**Category:** Ansible Project\
**Created:** [April 22, 2012, 1:37am UTC](https://forum.ansible.com/t/heres-how-to-access-facts-from-other-hosts-advanced-feature/11430 "2012-04-22T01:37:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [April 22, 2012, 1:37am UTC](https://forum.ansible.com/t/heres-how-to-access-facts-from-other-hosts-advanced-feature/11430/1 "2012-04-22T01:37:20Z")

</div>

Suppose you are configuring a Java app server, and it was neccessary  
to put something like an IP address + port number of a database server  
in the XML configuration file for the app server. This is somewhat  
of an advanced need as TYPICALLY, I'd  
think you'd just stick a load balancer in front of things and use well  
known ports. However, that's not ALWAYS the case, and you  
occasionally need to get the data from facts on certain nodes to use  
in templates for OTHER nodes.

I just implemented a way to access variables set or determined from  
other hosts. If you are familiar with how this works in Puppet  
(requiring storeconfigs (database) plus weird modified spaceship  
operators), this is going to be REALLY nice. Orchestration between  
multiple tiers of a software system is going to be incredibly easy  
with this.

The change enabling this is now available on the integration branch,  
but it works just like this:

# an example of accessing an ansible fact (which ARE somewhat nested)  
{{ hostvars['bar.example.com']['ansible\_eth0']['ipv4']['address'] }}

# an example of accessing a facter fact (which aren't nested)  
{{ hostvars['foo.example.com']['facter\_hostname']

# an example of defining a host variable via the new YAML host file  
system, that was defined like so:

- host: asdf  
&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;database\_port: 1234

{{ hostvar['127.0.0.1']['database\_port'] }}

I'll update the web documentation on this after 0.0.3 is released,  
along with documentation about available Ansible facts.

Note that because of the way this works, if you wish to use the  
variables from one set of hosts in another set of hosts, you have  
to have either included that host in the current play, or a previous  
play. If your playbook needs the appservers to point at the  
dbservers, you need to have at least a play with zero or more tasks  
first calling the dbservers to load up their data.

I suspect most people won't need this, but the fact that we can do it  
-- and that it required so little in terms of code changes -- is a  
pretty big deal.

--Michael

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [April 22, 2012, 1:44am UTC](https://forum.ansible.com/t/heres-how-to-access-facts-from-other-hosts-advanced-feature/11430/2 "2012-04-22T01:44:04Z")

</div>

Folks who don't code a lot of Python may also like to know that the  
following syntax works:

{{ hostvars.get('127.0.0.1').get('some\_fact') }}

# and with defaults, if you ever need this:

{{ hostvars.get('127.0.0.1', {}).get('some\_fact', 'default') }}

---

<div class="post-metadata">

**Author:** ![Michel\_Blanc1](https://avatars.discourse-cdn.com/v4/letter/m/fbc32d/32.png) [@Michel\_Blanc1](https://forum.ansible.com/u/Michel_Blanc1)\
**Post date:** [April 22, 2012, 9:41am UTC](https://forum.ansible.com/t/heres-how-to-access-facts-from-other-hosts-advanced-feature/11430/3 "2012-04-22T09:41:19Z")

</div>

Hello folks & Michael,

This sounds really nice. Does this mean I can do something like this :  
(excuse my python)

$ cat hosts.j2  
# Auto-generated /etc/hosts  
{% for k,v in hostvars.iteritems() %}  
{{v['ansible\_eth0']['ipv4']['address']}} {{ k }}  
{% endfor %}

?

Would be very useful for me to automatically generate monitoring  
configuration for the host list.

Thanks,

M

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [April 22, 2012, 12:57pm UTC](https://forum.ansible.com/t/heres-how-to-access-facts-from-other-hosts-advanced-feature/11430/4 "2012-04-22T12:57:17Z")

</div>

> Hello folks & Michael,
> 
> This sounds really nice. Does this mean I can do something like this :  
> (excuse my python)
> 
> $ cat hosts.j2
> 
> # Auto-generated /etc/hosts
> 
> {% for k,v in hostvars.iteritems() %}  
> {{v[‘ansible\_eth0’][‘ipv4’][‘address’]}} {{ k }}  
> {% endfor %}

Yes, exactly like that!

Side note – That would include all of your hosts, so maybe you’d want a way to decide which ones not to include… I’ll open up an RFE for including a node’s group  
membership in hostvars, so the templates can “know” what groups it is a part of.

–Michael

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [April 22, 2012, 1:01pm UTC](https://forum.ansible.com/t/heres-how-to-access-facts-from-other-hosts-advanced-feature/11430/5 "2012-04-22T13:01:38Z")

</div>

Here’s what I was talking about about it being nice if the host could see what groups it was in:

[https://github.com/ansible/ansible/issues/196](https://github.com/ansible/ansible/issues/196)

Not super critical, just maybe nice to have. For example if your monitoring application wanted to just monitor web servers and database servers, this would be an easy way  
to get the list of all web servers and database servers in a template.
