前言
很多新手初学 Ans 都会踩一个致命坑:剧本中途安装软件后,facts 里依旧查不到新装的包。本文结合实验,从yum_repository/rpm_key/dnf/package_facts四大模块实战入手,讲清 facts 静态快照原理、变量引用规范、生产最优写法(register 替代频繁刷新 facts),全文附带可直接运行完整 playbook。
一、实验需求
批量给所有 Linux 主机完成三件事:
源地址:http://materials.example.com/yum/repository,GPG 密钥:http://materials.example.com/yum/repository/RPM-GPG-KEY-example
二、完整最终可用 Playbook(repo_playbook.yml)
—
– name: Repository Configuration
hosts: all
vars:
custom_pkg: simple-agent #全局统一软件名变量
tasks:
#任务1:初次采集全量rpm包信息,存入ansible_facts.packages(拍第一张快照)
– name: Gather Package Facts Before Install
ansible.builtin.package_facts:
manager: auto #自动识别dnf/yum/apt,跨系统兼容
#任务2:安装前校验,无包才打印,不存在跳过
– name: Show pkg info before install
ansible.builtin.debug:
var: ansible_facts['packages'][custom_pkg]
when: custom_pkg in ansible_facts['packages'] #when表达式不用{{}}
#任务3:生成自定义yum源文件
– name: Create internal yum repo
ansible.builtin.yum_repository:
name: example-internal #[]内仓库ID
description: Example Inc. Internal YUM repo
file: example #生成example.repo
baseurl: http://materials.example.com/yum/repository/
gpgcheck: yes #开启包签名校验
#任务4:远程下载导入GPG公钥
– name: Import repo GPG public key
ansible.builtin.rpm_key:
key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
state: present
#任务5:安装目标软件,模块参数必须{{}}引用变量
– name: Install {{ custom_pkg }} software
ansible.builtin.dnf:
name: "{{ custom_pkg }}"
state: present
#关键:安装完必须重新采集facts刷新数据(实验核心)
– name: Refresh package facts after install
ansible.builtin.package_facts:
manager: auto
#任务6:刷新后正常输出软件版本信息
– name: Show pkg info after install
ansible.builtin.debug:
var: ansible_facts['packages'][custom_pkg]
when: custom_pkg in ansible_facts['packages']
三、关键知识点 1:变量{{ }}什么时候加、什么时候不加
1、模块参数值 → 必须加{{ 变量名 }}
dnf:
name: "{{ custom_pkg }}" #字符串赋值,需要jinja渲染替换
2、when 条件表达式 → 直接写变量,不用 {{}}
when: custom_pkg in ansible_facts['packages']
Ansible 会自动解析 when 内的表达式,内置变量识别,套{{}}反而报错。
四、关键知识点 2:四大软件管理模块详解
1、yum_repository:自动生成 repo 源,告别手动写配置
| name | repo 唯一 ID([example-internal]) |
| file | 生成文件名xxx.repo,填 example→/etc/yum.repos.d/example.repo |
| baseurl | yum 仓库远程地址 |
| gpgcheck:yes | 开启 rpm 校验,必须配合 rpm_key 导入公钥 |
2、rpm_key:批量导入 RPM 签名公钥
- state:present:导入密钥;absent:删除密钥;
- 密钥支持 URL / 本地文件路径,gpgcheck=yes缺少密钥直接安装报错。
3、dnf:跨 RHEL 系列安装卸载软件
state:present安装、absent卸载、latest升级。 批量卸载测试临时命令:
ansible all -m dnf -a 'name=simple-agent state=absent'
4、package_facts
核心结论:只在执行瞬间采集系统软件快照,剧本后续增删软件,内存中的 facts 永远不变! 类比:拍照,人换衣服,老照片不会自动更新,必须重新拍照。
五、实验两次运行现象对照
①未加后置刷新任务(错误写法)
Gather Facts(无包) → debug跳过 → 建源→导密钥→安装changed → debug仍然跳过
软件装上了,facts 数据没更新。
②增加安装后 package_facts 刷新(标准写法)
初次采集→跳过→建源→导密钥→安装changed→刷新facts→正常打印包信息
六、生产优化:不想频繁执行 package_facts?用 register 替代(企业首选)
频繁反复执行package_facts效率低,生产不依赖 ansible_facts 查安装结果,改用 register 捕获任务实时输出,不用刷新任何 facts:
– name: Install {{ custom_pkg }}
dnf:
name: "{{ custom_pkg }}"
state: present
register: install_result #捕获本次安装实时结果
– name: Print install real result
debug:
var: install_result
register 优势
七、延伸:想全局缓存 facts 减少重复采集
大规模集群不想每次 play 开头全量 setup 采集,可开启 facts 缓存(ansible.cfg 配置 gathering=smart,redis/jsonfile 缓存 facts),同一机器短时间内复用上次采集数据,适合千台以上集群运维。





