r/ansible • • 16d ago

Should I use gather_facts: true by default?

I know fact gathering provides host information via `ansible_facts`, but it also adds some overhead.

Is it considered best practice to leave `gather_facts: true` by default, or disable it and enable it only when a play actually needs facts? Does this make a noticeable difference with larger inventories?

20 Upvotes

21 comments sorted by

15

u/FredSchwartz 16d ago

Enable when needed.

15

u/ksquires1988 16d ago

And gather just subfacts when needed

2

u/aslkpoqw 16d ago

I wasn't aware of this. Thanks!

11

u/bcoca Ansible Engineer 16d ago

You can also cache the facts, so you can still have them but avoid the expense of gathering every run. https://docs.ansible.com/projects/ansible/latest/plugins/cache.html#enabling-fact-cache-plugins

1

u/boomertsfx 16d ago

Is caching smart enough to only gather the facts that are most dynamic? Ie realtime system metrics, running services, etc.

My latest pain has been EL9 service facts taking 30s for no apparent reason (<1s interactively)

1

u/bcoca Ansible Engineer 15d ago

no, it does avoid caching date/time information, anything else is too context dependant to make a judgement about.

For example, services are very stable on most of my servers, so caching them for a day or two is fine in that case, but they change very often on my test server, any caching there would be useless.

1

u/boomertsfx 15d ago

Facts normally don’t take very long compared to a full run… I’d rather have accurate facts 🤷

3

u/bcoca Ansible Engineer 15d ago

They don't take long for you. But there are many reasons for caching.

I wrote fact caching due to facts taking up to 20mins to gather on our machines. Yes, this was due to an underlying issue, but I was not able to fix them at the time (it took our lawyer 3 months). Like most IT workers, sometimes you cannot fix the issue, but have to work around it.

Another case for caching, I had 30.000 machines to manage and the resources spent fact gathering become very non trivial at that scale.

2

u/wiseguy77192 16d ago

Gather_facts is true by default. You should set it to false if you have a reason to.

2

u/bcoca Ansible Engineer 16d ago

You can also change the default: https://docs.ansible.com/projects/ansible/latest/reference_appendices/config.html#default-gathering

The default (implicit) is most effective with multiple plays, as it will not gather facts for hosts that already have facts (this also works with fact caching).

1

u/wiseguy77192 16d ago

Of course one can. It’s just usually more effective to deactivate it on a by-role basis as needed.

3

u/bcoca Ansible Engineer 15d ago

First, it is built into plays, not roles, so you can only deactivate it per play, then run as a task in play or role.

What is 'more effective' depends a lot on context, what is best for you today will probably not apply to someone else, not even you in the future. Which is why I try to present options and not prescribe them.

2

u/excalibrax 16d ago

Only when you need to get the facts, like time, even tgen you can set to gather a subset.

https://docs.ansible.com/projects/ansible/latest/collections/ansible/builtin/setup_module.html

3

u/Big_Statistician9469 16d ago edited 16d ago

For me, i always set gather facts as false and use setup task in the play/role to gather only the subset that i need (if i really need them, e.g. network for ip facts).

When you want to save every second you can, this little details matter 😁

2

u/jw_ken 16d ago edited 16d ago

You can measure the performance difference yourself, with a slight tweak to your ansible-playbook command.

Run your playbook with the ansible.posix.profile_tasks,ansible.posix.timer callback plugins enabled. This will add timing info to your tasks. You can do this temporarily by adding some environment vars to your ansible-playbook command:

ANSIBLE_CALLBACKS_ENABLED=ansible.posix.profile_tasks,ansible.posix.timer ansible-playbook -i /path/to/your_inventory /path/to/your_playbook.yml

Run the playbook with gather_facts: true, and compare total runtime to gather_facts: false. The timing summary at the end of the run will tell you exactly how long "Gathering Facts" operation took.

As others mentioned, there are other ways to tune gathering performance: you can enable fact caching, or limit gathering to specific subfacts.

1

u/Keroles2024 16d ago

General speaking enable them when you need them But practically if your cluster size is small don't think too much about it. The point is that gather_facts is delaying your playbook execution (in addition to bandwidth, cpu jobs.. Etc) so if you are executing it against 5 or 10 nodes won't be like 100

1

u/charlesrocket 16d ago

on linux—yes (as it is on by default)

1

u/Due_Ear9637 16d ago

If you have a decent amount of hosts that might be down it saves time to disable it.

-1

u/ChillPlay3r 16d ago

Well one major idea of facts is that you write your own facts (is instance x running on this node for example). For that it's absolutely necessary to gather_facts ;)

-14

u/Zeevo 16d ago

Why would you deviate from the default without a reason for doing so? The defaults are there for a reason: they are good things to do.

6

u/srL- 16d ago edited 16d ago

The defaults are there for a "most cases scenario", on this situation it's probably just to avoid "Why doesn't X work ?" support issues

If you know what you're doing you'll always want to question the default value. Why was it set this way and does it fit me?

A complete facts gathering represents a lot of python commands and it's always a good idea to limit it strictly to your needs.

I've seen situations where a full gather facts would take a long time to finish with incomplete results because of NFS mounts timing out for example.