一次变更要留下什么
事后被问到“上周那个改动是谁做的、改了哪些文件、用的是哪版脚本”,能不能立刻答上来,取决于执行时留了多少痕迹。可追溯的最小集合是五样:执行了哪个版本的代码、用的是什么清单与参数、操作了哪些主机、具体改了什么内容、结果如何。缺任何一样,复盘时都要靠回忆补。
基本信息
| 执行日志 | 配置项把输出落盘,或由回调插件写入日志系统 |
|---|---|
| 内容差异 | 执行时附加差异输出,得到逐行的改动记录 |
| 代码版本 | 仓库提交号与标签;依赖用锁定文件固定版本 |
| 清单快照 | 执行用的清单与变量取值随运行一起归档 |
| 执行主体 | 谁在何时执行;调度平台通常自带作业记录 |
| 保存期限 | 按合规要求设置,至少覆盖一次完整的变更窗口 |
典型使用场景
- 故障复盘:定位是哪次变更引入的问题、当时改了哪些配置项
- 审计问询:证明某台主机上的改动经过审批流程、由谁执行
- 回滚依据:按差异记录反推需要恢复成什么内容
- 版本排查:同一剧本不同版本行为不同,靠提交号确认当时用的哪一版
- 配置漂移分析:对比历史差异记录,看现网被手工改动的痕迹
- 知识沉淀:把重要变更的执行差异整理进运维记录
留痕的配置与执行方式
留痕的配置与执行方式
# ansible.cfg:把每次执行落盘
[defaults]
log_path = /var/log/ansible/ansible.log
callbacks_enabled = profile_tasks # 附带耗时信息(名称随版本变化)
# 执行时带上差异,得到逐行改动
# ansible-playbook -i inventory/production site.yml --diff
#
# 归档建议(随运行一起保存):
# 1) 执行日志:包含任务名、changed/ok、失败信息
# 2) 差异输出:本次真实改动的逐行记录
# 3) 代码版本:git rev-parse HEAD 与最近标签
# 4) 依赖锁定:集合与角色版本清单
# 5) 清单与变量取值:本次实际使用的那一份(不含秘密)
# 6) 生效配置:dump 出的非默认配置项,排除配置差异造成的干扰痕迹对应的问题
| 留痕内容 | 回答的问题 | 常见缺失原因 |
|---|---|---|
| 执行日志 | 做了什么、结果如何 | 只在终端看,没有落盘 |
| 差异输出 | 具体改了哪些行 | 未加差异开关,只留下 changed 计数 |
| 代码版本与依赖版本 | 用的是哪一版 | 依赖不锁定,事后无法还原 |
| 清单与变量取值 | 操作了谁、参数是什么 | 清单随环境变化,事后找不到当时那份 |
| 执行者与时间 | 谁在什么时候做的 | 手动执行无记录,未接入调度平台 |
| 生效配置快照 | 执行环境的默认值是否被改过 | 忽略了本地配置差异造成的干扰 |
任务名在这里会直接发挥作用:日志里显示的是任务名,写得清楚,变更记录本身就是一份可读的改动清单,不需要再逐行读输出。
日志与差异输出会把配置内容、变量取值原样保存,其中可能含内部地址与凭据。归档前应确认敏感任务已设置 no_log,并对归档目录做访问控制与保留期限管理,避免留痕变成泄露源。
落地做法
把留痕固化到流程里而不是靠自觉:日志路径统一配置,差异开关作为执行命令的固定组成部分,代码版本与依赖锁定文件由流水线自动附加,归档产物随流水线附件保存。这样每次执行都自动形成一份完整记录,不依赖执行人当时是否记得。