J1raya
J1raya

Reputation: 340

Ansible Gethering Cached OS facts Based on Conditions

I'm using the following to gather certain OS facts based on the ansible_system fact:

---
- name: Gather facts from all target hosts
  hosts: all
  gather_facts: false
  tasks: 

    - name: Gather OS information for linux
      set_fact:
        os_version: "{{ ansible_facts[distribution] }} {{ ansible_facts[distribution_version] }}"
      when: ansible_facts[system] == "Linux"

    - name: Gather OS information for Windows
      set_fact:
        os_version: "{{ ansible_facts[ansible_os_name] }}"
      when: ansible_facts[system] is search("Win")     

    - name: Set unknowm if not linux or windows
      set_fact:
        os_version: 'unknown'
      when: 
      - not ansible_facts[system] is search("Win")  
      - not ansible_facts[system] == "Linux"

I get the following error for all hosts in the inventory:

"msg": "The conditional check 'ansible_facts[system] == "Linux"' failed. The error was: error while evaluating conditional (ansible_facts[system] == "Linux"): 'system' is undefined.

But when checking all of the hosts this is failing against, I've verified all have that cached fact, for example:

  "ansible_system": "Linux",
  "ansible_cmdline": {
    "ro": true,
    "root": "UUID=fcd2fe34-d0d2-4d03-8c17-0a5d8e61cfee",
    "BOOT_IMAGE": "/boot/vmlinuz-5.4.0-193-generic",
    "maybe-ubiquity": true   },

Am I trying to access the fact in the incorrect way?

I believe I can use either

ansible_facts[system] == "Linux"

or

ansible_system == "Linux"

Upvotes: 1

Views: 78

Answers (2)

J1raya
J1raya

Reputation: 340

Thanks kindly @U880D

I did indeed need to enable facts and have updated ansible.cfg. We have a complex environment that uses different group_vars across different cloud environments/hypervisors/Active Directory Domains/etc in combination with different custom credential objects, so the default gather_facts directive won't authenticate.

I've added tasks that include our group_vars role and ansible.builtin.setup task to gather facts which I can now see returned:

---
- name: Gather facts from all target hosts
  hosts: all
  gather_facts: false
  become: true
  become_user: root
  collections:
    - collections.techops

  pre_tasks:
    - name: Include GroupVar role
      ansible.builtin.include_role: 
        name: inculde-groupvars
      vars:
        include_groupvars: allenvs


  tasks:

    - name: debug
      debug:
        msg: "{{ ansible_connection }} {{ ansible_user }} {{ ansible_password }} {{ ansible_become_method }} {{ become_method | default('NA') }}"
      when: debug | default('false') | lower == "true"

    - name: Gather Facts
      ansible.builtin.setup:
        gather_subset: 
          - 'all'
          - '!min'
      register: gather_result
      ignore_unreachable: yes
      when: gather_factsvar | default('false') | lower == "true" 

I was also missing ' ' around the facts objects, i.e:

From:

ansible_facts[system]

To:

ansible_facts['system']

The rest of the tasks worked with these adjustments:

    - name: Gather OS information for linux
      set_fact:
        os_version: "{{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
      when: ansible_facts['system'] == "Linux"
    
    - name: Gather OS information for Windows
      set_fact:
        os_version: "{{ ansible_facts['os_name'] }}"
      when: ansible_facts['system'] is search("Win")     
    
    - name: Set unknowm if not linux or windows
      set_fact:
        os_version: 'unknown'
      when: 
      - not ansible_facts['system'] is search("Win")  
      - not ansible_facts['system'] == "Linux" 

Upvotes: 0

U880D
U880D

Reputation: 12142

Q: "I'm using the following to gather certain OS facts based on the ansible_system fact"

No, according your

gather_facts: false

you do not gather facts at all.

Q: "I've verified all have that cached fact"

Yes, but that's not how it works depending on the configuration. See in example How to cache Ansible facts

fact_caching_timeout sets the expiration timeout in seconds for the cache plugin data. To ensure data does not expire, set this option to 0. ... When fact_caching_timeout expires, all playbooks that require facts and have the option gather_facts set to false will not work. To make them work, refresh the fact data in the cache.

A minimal example playbook

---
- hosts: test
  become: false
  gather_facts: false

  tasks:

  - debug:
      var: ansible_facts

will result into an output of

TASK [debug] *********
ok: [test.example.com]
  ansible_facts: {}

even if there is configured in ansible.cfg

fact_path               = /etc/ansible/facts.d
fact_caching            = yaml
fact_caching_connection = /tmp/ansible/facts_cache
fact_caching_timeout    = 129600

and there are already cached facts available. Setting the fact_caching_timeout = 0 would result into an output of

TASK [debug] *********
ok: [test.example.com]
  ansible_facts:
    discovered_interpreter_python: /usr/libexec/platform-python
    test: test

the cached facts.

Further Documentation

Upvotes: 3

Related Questions