The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Read system information in an Ansible playbook from the ansible_facts dictionary, for example ansible_facts['distribution'] or ansible_facts['os_family']. Ansible normally gathers these facts at the start of each play, so you can use them in tasks, conditionals, handlers, and templates without writing a separate discovery task. Use the dictionary form rather than bare variables such as ansible_distribution: injected fact variables are deprecated, and their default availability is planned to change in ansible-core 2.24.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
The correct syntax for reading Ansible system facts
Facts are key-value data collected from each managed host. The supported access pattern is the ansible_facts dictionary:
As an Amazon Associate I earn from qualifying purchases.
Recommended Free Tools
- name: Show the operating-system family
ansible.builtin.debug:
msg: "{{ ansible_facts['os_family'] }}"
- name: Show the distribution and release
ansible.builtin.debug:
msg: "{{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
The key inside the dictionary does not include the ansible_ prefix. Use ansible_facts['system'], not ansible_facts['ansible_system']. The latter looks plausible but is not the normal fact name.
Dot notation can be convenient for simple keys, but bracket notation is clearer in documentation and safer when a key contains characters that are not valid in a variable name:
#1 Best Overall
- [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
- [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
- [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
- [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
- [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.
{{ ansible_facts['hostname'] }}
{{ ansible_facts['default_ipv4']['address'] }}
{{ ansible_facts['mounts'] }}
Fact availability still depends on successful collection and on the modules and subsets you ask Ansible to collect. Treat a fact as host data, not as a constant: two hosts can return different values, and some keys can be absent on a particular operating system or virtualized environment.
What facts contain and why they matter
The default setup fact module reports information such as the operating-system family, distribution, release, kernel, architecture, hostname, interfaces, addresses, processor details, memory, mounts, and several hardware and virtualization attributes. Exact keys vary with the target platform and the modules available on that host.
Use facts when a play must adapt to the host rather than assume that every machine is identical. Typical decisions include selecting a package manager, choosing a service name, placing files in an operating-system-specific path, or enabling a feature only when hardware or a kernel capability is present.
| Reader need | Fact expression | Typical use |
|---|---|---|
| Kernel family | ansible_facts['system'] |
Branch between Linux, Windows, and other systems. |
| Distribution family | ansible_facts['os_family'] |
Choose a family-level package or configuration path. |
| Distribution name | ansible_facts['distribution'] |
Handle a distribution-specific exception. |
| Distribution release | ansible_facts['distribution_version'] |
Apply a version-dependent setting. |
| Host name | ansible_facts['hostname'] |
Build host-specific names or diagnostics. |
| Primary IPv4 address | ansible_facts['default_ipv4']['address'] |
Render a configuration containing the default address. |
Do not assume that a nested key exists merely because it exists on your workstation. Guard optional data with a default or a conditional before dereferencing it.
How fact gathering works
The ansible.builtin.gather_facts module is part of ansible-core. A play calls it automatically unless gathering is disabled. By default, the module uses ansible.builtin.setup to collect facts from the remote host.
The implicit gathering happens before the first task in each play. You can make that behavior explicit when you want the play’s intent to be obvious:
Free tools Windows power users keep installed
One-click scans. No signup required.
- name: Configure web servers
hosts: web
gather_facts: true
tasks:
- name: Display the target platform
ansible.builtin.debug:
var: ansible_facts['distribution']
Calling the module yourself is useful when you need to gather facts at a particular point, after changing host state, or with specific module options:
Rank #2
- 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
- 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
- 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
- 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
- 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.
- name: Gather system facts explicitly
hosts: all
gather_facts: false
tasks:
- name: Collect facts now
ansible.builtin.gather_facts:
- name: Use the newly collected data
ansible.builtin.debug:
msg: "{{ ansible_facts['system'] }} on {{ ansible_facts['hostname'] }}"
Use the fully qualified module name, ansible.builtin.gather_facts, in new playbooks. Fully qualified names make it clear which collection supplies the module and avoid collisions with modules from other collections.
A practical playbook pattern
1. Gather facts before the decision point
Leave the default gather_facts: true in place when tasks need host information. If an earlier task changes the operating system state and you need fresh values, run ansible.builtin.gather_facts again after that task.
2. Inspect the exact data returned
Use ansible.builtin.debug while developing a play. Printing the complete dictionary can expose sensitive or very large data, so start with one key:
- name: Inspect selected facts
ansible.builtin.debug:
msg:
hostname: "{{ ansible_facts['hostname'] | default('unknown') }}"
system: "{{ ansible_facts['system'] | default('unknown') }}"
family: "{{ ansible_facts['os_family'] | default('unknown') }}"
If you need to explore all returned keys on a test host, temporarily use:
- name: Dump all gathered facts during troubleshooting
ansible.builtin.debug:
var: ansible_facts
Remove broad dumps from routine runs. Facts can include network addresses, mount details, hardware identifiers, and other information you may not want in logs.
3. Use facts in a conditional
- name: Install a package on Debian-family systems
ansible.builtin.apt:
name: nginx
state: present
when: ansible_facts['os_family'] == 'Debian'
- name: Install a package on Red Hat-family systems
ansible.builtin.dnf:
name: nginx
state: present
when: ansible_facts['os_family'] == 'RedHat'
For a distribution-specific branch, compare ansible_facts['distribution'] instead of the broader family. Keep a deliberate failure path for unsupported systems so a new platform does not silently receive the wrong configuration.
4. Render a template or task argument
- name: Write a host identification file
ansible.builtin.copy:
dest: /etc/managed-host
content: |
name={{ ansible_facts['hostname'] }}
platform={{ ansible_facts['distribution'] }}
release={{ ansible_facts['distribution_version'] }}
Facts are evaluated on the managed host’s context. In a template, use the same dictionary expressions; in a task’s when clause, omit the surrounding Jinja delimiters.
Rank #3
- [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
- [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
- [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
- [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
- [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by
5. Handle absent or undefined values
Some fact keys are platform-dependent. The default filter prevents an undefined value from stopping a task:
- name: Report a default address when one exists
ansible.builtin.debug:
msg: "address={{ ansible_facts['default_ipv4']['address'] | default('not reported') }}"
For nested data, guard the parent object as well when it may not exist:
- name: Use a default IPv4 address only when the structure is present
ansible.builtin.debug:
msg: "{{ ansible_facts['default_ipv4']['address'] }}"
when:
- ansible_facts['default_ipv4'] is defined
- ansible_facts['default_ipv4']['address'] is defined
Disabling or limiting fact collection
Skip gathering when a play does not need system data
Set gather_facts: false at play level to skip the automatic setup step:
- name: Run a fact-independent operation
hosts: all
gather_facts: false
tasks:
- name: Create a marker directory
ansible.builtin.file:
path: /var/lib/my-job
state: directory
mode: '0755'
This can reduce startup work, but every later task must avoid ansible_facts unless you explicitly gather them. A common failure is disabling gathering for speed and then receiving an undefined-variable error in a conditional or template.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteCollect only selected categories
The setup module supports subsets, and tutorials commonly show values such as network or hardware-related subsets. For example:
- name: Gather only network-related facts
ansible.builtin.gather_facts:
gather_subset:
- network
Subset names and the resulting keys depend on the ansible-core version and setup-module documentation you are using. Verify the accepted values for your installed version before relying on a narrow subset in a reusable role. If a required key is missing, collect the broader default set or add the appropriate subset.
Understand parallel collection
ansible.builtin.gather_facts can run fact modules in parallel. A serial mode is available when deterministic merge order matters. Parallel collection is generally faster; serial collection gives predictable ordering when multiple fact modules provide overlapping data. Choose deliberately rather than changing the setting to hide a data conflict.
Rank #4
- Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
- Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
- All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
- Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
- Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.
Why ansible_distribution works today but should be replaced
Ansible can inject gathered facts as top-level variables when INJECT_FACTS_AS_VARS is enabled. With that compatibility behavior, both of these may appear to work:
{{ ansible_distribution }}
{{ ansible_facts['distribution'] }}
They are not equivalent from a maintenance perspective. The bare form depends on configuration-driven variable injection, while the dictionary form is the explicit facts API. Accessing injected names produces deprecation warnings in ansible-core 2.20 and later.
The current default for INJECT_FACTS_AS_VARS is True, but the default is planned to switch to False in ansible-core 2.24. That release plan is not a guarantee of the exact date or behavior, so make the migration before upgrading rather than waiting for the default to change.
| Legacy expression | Preferred expression | Reason |
|---|---|---|
ansible_distribution |
ansible_facts['distribution'] |
Does not rely on injected variables. |
ansible_os_family |
ansible_facts['os_family'] |
Uses the documented dictionary namespace. |
ansible_system |
ansible_facts['system'] |
Removes the duplicated prefix inside the dictionary. |
ansible_hostname |
ansible_facts['hostname'] |
Continues to work when injection is disabled. |
Search roles, playbooks, templates, and conditionals for ansible_ variables, then convert each reference to its dictionary counterpart. Do not mechanically prepend ansible_facts[' and append ']: the dictionary key drops the leading ansible_.
Testing for the upcoming injection change
Set the option to disable injection in a test configuration and run your complete automation suite. The configuration option belongs under [defaults] in ansible.cfg:
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →[defaults]
inject_facts_as_vars = False
The environment-variable form is also documented by Ansible’s porting guidance; check the exact spelling emitted by ansible-config dump for the ansible-core version installed in your CI environment. Configuration names and environment-variable names are not always written identically.
Run representative plays against every supported operating system with injection disabled. Pay particular attention to:
Best Value
whenclauses that compareansible_distributionoransible_os_family.- Templates that reference bare hostname, interface, mount, or processor variables.
- Roles that pass fact values through defaults or task includes.
- Dynamic includes whose file name is built from a fact.
Ansible’s linter does not currently report this particular deprecation, so a clean lint run does not prove that a role is ready. Runtime tests with injection disabled are the reliable check.
Fact-gathering failures and fixes
“The variable is undefined”
- Confirm that the play has not set
gather_facts: false. - Check that a preceding task did not rely on facts gathered in a different play; facts are collected per play unless you gather them again.
- Use
ansible.builtin.debugto inspectansible_factson the failing host. - Replace a bare variable with the dictionary form and verify the key spelling.
“The key is missing”
A missing nested key can be normal on a host without that device, interface, filesystem, or platform feature. Add a defined check or a default value, or collect a broader setup subset if you intentionally limited collection.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problems“I see deprecation warnings”
Find the task, template, or role using an injected ansible_* name. Convert it to ansible_facts['key']. If the warning originates in a third-party component, check whether a newer release has migrated. The Ansible 13 porting guidance notes a special caveat for community.sops.load_vars: its implementation can emit repeated warnings because those plugins historically lacked an alternative way to set variables, and the guidance says not to convert SOPS-loaded variables to ansible_facts.
“Facts are stale”
Facts represent the state at collection time. If a task changes networking, packages, mounts, or another fact-producing property and a later task needs the new value, call ansible.builtin.gather_facts again at that point. Gathering at the start of the play does not automatically refresh values after every task.
“Gathering is slow”
Skip it for plays that truly do not need host information, or use a carefully selected subset. Measure the effect across your inventory: a narrow subset can improve startup time but may remove keys that roles silently depend on.
Inspecting facts outside a playbook
For a quick inventory check, the official module documentation shows this ad hoc command:
ansible all -m ansible.builtin.gather_facts --tree /tmp/facts
The command writes each host’s gathered facts to a file below /tmp/facts. Review those files to discover the exact key names and values returned by your inventory before writing conditionals. Use a directory with appropriate permissions because fact files can contain detailed host information.
Ad hoc output is useful for exploration, but keep production logic in version-controlled playbooks and roles. Once you know the key you need, reference it through ansible_facts and add a test for hosts where that key may be absent.
A migration checklist for existing automation
- Inventory every bare
ansible_*fact reference in YAML, Jinja templates, and role defaults. - Map each name to the dictionary key without the leading
ansible_; for example,ansible_distributionbecomesansible_facts['distribution']. - Check plays that disable gathering and either enable it or add an explicit
ansible.builtin.gather_factstask. - Protect optional and nested keys with
is definedtests ordefaultvalues. - Run the suite with
inject_facts_as_vars = Falsein a test configuration. - Test on every operating-system family and release you claim to support.
- Keep the dictionary form in new code even while older roles still run with injection enabled.
Recommended rule of thumb
Gather facts when the play needs host-specific decisions, read them as ansible_facts['key'], and disable gathering only when you have confirmed that no task, template, or role depends on it. This approach works with the current defaults, avoids deprecation warnings, and prepares playbooks for the planned change to fact-variable injection in ansible-core 2.24.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.




