You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible基于条件调用缓存OS facts遇'system'未定义错误的排查

Ansible事实访问方式错误排查

问题场景

我使用以下Playbook基于ansible_system事实收集特定OS信息:

---
- 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"

报错信息

所有清单内主机均出现如下错误:

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

缓存事实示例

经核查,报错主机均存在缓存的ansible_system事实,示例如下:

"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
  }

疑问

我认为可以通过ansible_facts[system] == "Linux"或ansible_system == "Linux"两种方式访问该事实,请问是否是访问方式有误?


问题分析与修正

核心错误点

  1. 语法错误:字典键的访问方式
    原Playbook中ansible_facts[system]的写法错误——这里的system会被当作变量解析,但你并未定义这个变量,因此触发“'system' is undefined”报错。
    正确的字典访问方式有两种:

    • 字符串键索引:ansible_facts['system']
    • 点语法:ansible_facts.system
  2. gather_facts: false导致ansible_facts字典为空
    你在Playbook中设置了gather_facts: false,Ansible不会主动收集新的事实,此时ansible_facts字典是空的。而缓存的事实是以ansible_*开头的独立全局变量存在的(比如ansible_system、ansible_distribution),直接调用这些变量即可,无需通过ansible_facts字典。

  3. 其他变量访问错误
    原Playbook中ansible_facts[distribution]、ansible_facts[distribution_version]、ansible_facts[ansible_os_name]均存在相同语法错误,需对应修正为独立变量或正确的ansible_facts访问方式。

修正后的Playbook

方案一:使用缓存的事实(无需重新收集)

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

    - name: Gather OS information for Linux
      set_fact:
        os_version: "{{ ansible_distribution }} {{ ansible_distribution_version }}"
      when: ansible_system == "Linux"

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

    - name: Set unknown if not Linux or Windows
      set_fact:
        os_version: 'unknown'
      when: 
      - ansible_system is not search("Win")  
      - ansible_system != "Linux"

方案二:重新收集事实(去掉gather_facts: false)

---
- name: Gather facts from all target hosts
  hosts: all
  # 默认gather_facts: true,可省略
  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.os_name }}"
      when: ansible_facts.system is search("Win")     

    - name: Set unknown if not Linux or Windows
      set_fact:
        os_version: 'unknown'
      when: 
      - ansible_facts.system is not search("Win")  
      - ansible_facts.system != "Linux"

内容的提问来源于stack exchange,提问作者J1raya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 19:57:32