I know this has come up before, but I’ve not come across a real answer for it.
It’s common for a given host to depend on other hosts. App servers need to know the IP of databases they consume, databases need to know IPs of app servers that will be accessing them etc etc. In Ansible, the IP of other hosts is not automatically exposed. One practice I’ve seen is to run a dummy play just to force the other host’s facts to be discovered, but this gets tedious, clutters up scripts, and slows down their execution. I’m sure there must be a better way, but I don’t know what.
It’s really not bad, the “dummy” play just looks like this:
And that’s it, followed by other plays. You can limit it more of course, if you don’t need facts about every system in your inventory, but the setup step needs to be run on systems to get their facts. However it only needs to be run once, and after that all other plays can specify “gather_facts: no” to skip it.
But it gets more unwieldy if you're using roles. If my app role needs
to have the IPs for the databases I just have to hope that the
playbook that ends up running the tasks in my play have gathered all
the facts from those other systems. It gets even more
action-at-a-distance when your role is a dependency of another role.
My role can't force a fact gathering expedition to the other hosts.
Now you could say that if my role relies on this information I could
check if there are hosts in the group it cares about and then do a
fail if there aren't any, but lack of information doesn't necessarily
mean something is wrong. For instance, I have dev setups using the
same ansible stuff that I use in staging and production. Dev setups
don't need read-only database slaves running on their laptop. But
staging and production do. If gathering facts from all hosts shows
there aren't any db-slave servers, no biggie we just send the reads to
the master. But it's a problem in production if something changes in
some other role that depends on the app server role but doesn't happen
to gather facts from all the servers. Now production is sending all
reads to the master.
This is a very specific case that could probably be worked around in a
very verbose way, but it would all be simpler if my role could gather
facts as a task. Or maybe have some dependency on facts in the
meta/main.yml or something to make it explicit that I want me some
facts
True, the dummy boilerplate is small, but it has to precede every playbook. (I also thought it had to include at least one task to be in effect.)
The main issue is performance. I’m not dynamically provisioning, so these things never change. I thought maybe there’s some trick people are using to avoid the lookup, e.g. automatically using DNS/hosts file or auto-generating config files.
Is there an option to use the FQDNs in the inventory itself then?
If they resolve then you don't need to facts gather, right?
We’ve discussed fact caching options in the past.
There may be some in the future.
Until now, talk to the hosts first.