Modules can return regular return values as well as ansible_facts
, which automatically appear in the global namespace (unless you set INJECT_FACTS_AS_VARS=false
- though doing that will likely break a lot of playbooks and roles). Most modules returning ansible_facts
have the suffix _facts
in the module name, though there are exceptions (for example ansible.builtin.hostname
, which updates several hostname-related facts).
Right now the only guidance we give on whether a module should return ansible_facts
is here: Developing modules ā Ansible Community Documentation
Only use
ansible_facts
for information that is specific to the host machine, for example network interfaces and their configuration, which operating system and which programs are installed.
I want to start a discussion to elaborate on that, and I would even suggest to limit the use of ansible_facts
even further, and basically dissuade its use unless some very explicit exceptions.
The reason I want to start this discussion now is that thereās a new PR in community.general for adding a systemd_facts module, which I personally think should be an _info
module since the returned values arenāt āproperā facts: first you can limit the set of systemd units you want infos on, and second you can specify additional properties to query. Therefore the facts the module returns depend not only on the system (and on the time of querying), but also on the module settings.
Obviously all facts modules somehow depend on the time of invocation - if you list the disks in a system, someone might have pulled one out or put a new one in by the time your role/playbook uses the fact. (Plug and play, yay!) The same is true for mount facts (ansible.builtin.mount_facts
) - a task inbetween might have mounted, remounted, or unmounted something - and package facts (ansible.builtin.package_facts
) - a task inbetween might have installed, upgraded, or removed a package. Also the facts output of modules like ansible.builtin.mount_facts
depends on module options.
Iām still not sure what to think about facts like installed packages, mounts, and services, but generally I would say anything where facts retrieval can be configured (so that the values of the facts depend on these options) should very likely not facts, but _info
modules. community.general has its share of examples:
community.general.listen_port_facts
: depending on the program used and the optioninclude_non_listening
you get different results.community.general.snmp_facts
: these are actually queried for another host, not for the machine the module runs on!community.general.zfs_facts
: you can select the ZFS dataset, which properties to query, etc. This will be returned under the global nameansible_zfs_datasets
.community.general.zpool_facts
: thereās the ZFS pool name, and a properties selection, again returned under the global nameansible_zfs_pools
.
(I think these modules should be fixed, but itās better to wait until data tagging is there before we start deprecating something, since then we can finally properly deprecate return values, including facts )
The PR also falls into this category from my point of view: depending on the module options you get different output (the facts contain or not contain certain units, and some properties might be there or not).
WDYT?