Ansible教程:Facts 事实变量 作者:马育民 • 2026-09-27 09:51 • 阅读:10001 # 介绍 **Facts(事实)**:Ansible 通过 `setup` 模块,**自动采集被管理节点的系统信息**,存放在变量 `ansible_facts` 中,供 playbook 使用。 默认情况下,Ansible 执行 playbook 的**第一个动作就是收集 facts**,基于SSH在远端执行采集脚本,不需要在被控端安装agent。 ### 作用 **根据主机真实系统信息做条件判断、动态配置** 例如: - CentOS用yum,Ubuntu用apt - 不同系统生成不同配置文件 ### 两个写法 完全等价: - 推荐新标准:`ansible_facts['distribution']` - 旧版兼容:`ansible_distribution`(由 `INJECT_FACTS_AS_VARS` 控制是否注入顶层变量) # 查看 Facts ### 1. ad-hoc 命令查看全部facts ```bash ansible all -m setup -i ansible_client.ini ``` ### 2. playbook打印facts ##### 打印所有facts 创建 playbook 文件: ``` nano playbook_facts.yml ``` 内容: ```yaml --- - name: 打印所有facts hosts: all tasks: - name: 输出ansible_facts debug: var: ansible_facts ``` 执行: ``` ansible-playbook playbook_facts.yml -C -i ansible_client.ini ``` ##### 只打印某个facts 创建 playbook 文件: ``` nano playbook_facts_打印某个facts.yml ``` 内容: ```yaml --- - name: 混合 var / msg 打印facts hosts: all gather_facts: true tasks: - name: 操作系统发行版 debug: var: ansible_facts['distribution'] - name: 完整版本号 debug: var: ansible_facts['distribution_version'] - name: 短主机名 debug: var: ansible_facts['hostname'] - name: 总内存MB debug: var: ansible_facts['memtotal_mb'] - name: CPU逻辑核数 debug: var: ansible_facts['processor_vcpus'] ``` 执行: ``` ansible-playbook playbook_facts_打印某个facts.yml -C -i ansible_client.ini ``` # 常用内置Facts变量 | 变量 | 含义 | 示例 | |---|---|---| | ansible_facts['distribution'] | 操作系统发行版 | CentOS / Ubuntu / Debian / RedHat | | ansible_facts['distribution_major_version'] | 系统主版本 | 7 / 8 / 22 | | ansible_facts['distribution_version'] | 完整版本号 | 7.9 / 22.04 | | ansible_facts['os_family'] | 系统家族 | RedHat / Debian / Suse / Darwin | | ansible_facts['architecture'] | 系统架构 | x86_64 / aarch64 | | ansible_facts['kernel'] | 内核版本 | 5.15.0 | | ansible_facts['hostname'] | 短主机名 | web01 | | ansible_facts['fqdn'] | 完整FQDN域名 | web01.example.com | | ansible_facts['default_ipv4']['address'] | 默认网卡IPv4 | 192.168.1.10 | | ansible_facts['all_ipv4_addresses'] | 所有IPv4地址数组 | ["10.0.0.1","192.168.1.10"] | | ansible_facts['memtotal_mb'] | 总内存MB | 16384 | | ansible_facts['processor_vcpus'] | CPU逻辑核数 | 8 | | ansible_facts['pkg_mgr'] | 包管理器 | yum / dnf / apt | | ansible_facts['service_mgr'] | 服务管理器 | systemd / sysvinit | | ansible_facts['mounts'] | 磁盘挂载信息 | 数组,包含各分区容量 | | ansible_facts['env'] | 系统环境变量 | ansible_facts['env']['PATH'] | ### 打印上面的变量 创建 playbook 文件: ``` nano playbook_facts2.yml ``` 内容: ```yaml --- - name: 混合 var / msg 打印facts hosts: all gather_facts: true tasks: - name: 操作系统发行版 debug: var: ansible_facts['distribution'] - name: 系统主版本 debug: var: ansible_facts['distribution_major_version'] - name: 完整版本号 debug: var: ansible_facts['distribution_version'] - name: 系统家族 debug: var: ansible_facts['os_family'] - name: 系统架构 debug: var: ansible_facts['architecture'] - name: 内核版本 debug: var: ansible_facts['kernel'] - name: 短主机名 debug: var: ansible_facts['hostname'] - name: 完整FQDN域名(带容错,必须msg) debug: msg: "ansible_facts['fqdn'] : {{ ansible_facts['fqdn'] | default('N/A') }}" - name: 默认网卡IPv4(带容错,必须msg) debug: msg: "ansible_facts['default_ipv4']['address'] : {{ (ansible_facts['default_ipv4'] | default({})).address | default('N/A') }}" - name: 所有IPv4地址数组(带容错,必须msg) debug: msg: "ansible_facts['all_ipv4_addresses'] : {{ ansible_facts['all_ipv4_addresses'] | default([]) }}" - name: 总内存MB debug: var: ansible_facts['memtotal_mb'] - name: CPU逻辑核数 debug: var: ansible_facts['processor_vcpus'] - name: 包管理器 debug: var: ansible_facts['pkg_mgr'] - name: 服务管理器 debug: var: ansible_facts['service_mgr'] - name: 系统环境变量(带容错,必须msg) debug: var: ansible_facts['env'] ``` 执行: ``` ansible-playbook playbook_facts2.yml -C -i ansible_client.ini ``` # gather_facts 开关控制收集 ### 1. 关闭facts收集(提升执行速度,大批量主机常用) 关闭后,`ansible_facts` 变量不存在,不能使用系统信息判断。 ```yaml - name: 不收集facts hosts: all gather_facts: no tasks: - ... ``` ### 2. 按需收集子集(gather_subset,减少采集耗时) `setup` 模块支持只采集部分类别,减少开销: - `network`:网络信息 - `hardware`:硬件(CPU、内存、磁盘) - `virtual`:虚拟化信息 - `!all`:不收集全部,只指定子集 - `!min`:不收集最小基础集 示例:只采集网络+虚拟化信息 ```bash ansible all -m setup -a 'gather_subset=network,virtual' ``` playbook写法: ```yaml - hosts: all gather_facts: yes gather_subset: - network - virtual ``` # 实战:facts条件判断(最常用) ### 创建playbook文件 ``` nano playbook_facts_实战.yml ``` 内容: ```yaml --- - name: 根据系统安装web服务 hosts: all gather_facts: yes tasks: - name: RHEL系安装httpd yum: name: httpd state: present when: ansible_facts['os_family'] == "RedHat" # 如果 redRedHathat 家族的系统,就执行 yum 安装 - name: Debian系安装apache2 apt: name: apache2 state: present when: ansible_facts['os_family'] == "Debian" # 如果 Debian 家族的系统,就执行 apt 安装 ``` ### 模拟执行 ``` ansible-playbook playbook_facts_实战.yml --check -i ansible_client.ini ``` # Facts 优缺点与生产注意事项 ### 优点 1. 动态感知主机环境,实现一套playbook多系统兼容 2. 无agent,依托setup模块远程采集 3. 支持自定义facts,扩展业务信息 ### 缺点 1. **收集facts会消耗时间**,几百台以上主机批量执行,建议关闭或使用gather_subset子集 2. 采集需要Python(被控端必须有python2/python3;Windows需要powershell) 3. facts**只在本次play收集一次**,任务执行过程中系统变更不会自动刷新;如需重新采集,手动调用`setup`模块 ```yaml - name: 重新收集facts ansible.builtin.setup: ``` 4. 区分 **Facts** 和 **Magic Variables(魔术变量)**: - Facts:**被控主机系统信息**(ansible_facts) - Magic变量:ansible运行时/清单变量,如 `inventory_hostname`、`hostvars`、`groups`,不属于facts 原文出处:/show_1GW47heLmwH0.html