


在不削弱安全性的前提下,编写并审查 Ansible 基础设施自动化
让 AI 编写或修改 Ansible playbook 等基础设施自动化时使用。它会让所有 lint 和安全检查零警告通过,不把密码和密钥放进代码库,从最底层开始排查网络问题,证明测试能发现缺陷,并且只报告实际运行过的检查。
要使用这个AI规则
## 优先保证安全和稳定,只改动被要求的内容
将基础设施自动化视为安全关键代码:一个很小的配置错误也可能在不易察觉的情况下削弱隐私、访问控制、路由或服务可用性。
- 功能数量让位于稳定性,便利性让位于安全性,巧妙设计让位于清晰度。
- 只解决请求中明确提出的问题。把无关修复和推测性功能放到单独的工作中。
- 声称变更完成前,运行受影响的自动化来验证假设。
- 抵制新增依赖项。每个依赖项都会扩大攻击面和维护负担。
- 引入新抽象或配置选项前,遵循代码库的现有模式。
- 将每个新选项视为额外测试范围;只有用户存在已证实的需求时才添加。
- 当保留的状态可能掩盖缺陷时,使用全新部署进行行为测试。
## 让所有 lint 和安全检查零警告通过
审查前运行代码库完整的本地质量门。质量门应涵盖配置lint、YAML lint、语言lint、shell分析、静态安全分析、playbook语法检查和相关单元测试。
持续集成中不允许存在任何警告。在安全敏感型自动化中,看似只是外观问题的发现可能意味着template已损坏、file permission不安全,或真正的回归被重复噪声掩盖。
按以下顺序处理发现:
1. 修复根本问题。
2. 如果规则不适用于该代码库,在所属工具的配置中将其加入allowlist并解释原因。
3. 只有在别无选择时才使用inline suppression,同时指明确切规则并记录例外理由。
不要把发现转移到永久警告列表。规则必须通过,或者依据可长期追溯的理由被明确skip。
常见强制检查包括:
- YAML文档以`---`开头;parser要求时,为含义模糊的workflow key添加引号。
- 优先使用`failed_when`等明确失败条件,不要广泛使用`ignore_errors`。
- 保持Jinja2 spacing一致。
- 每个file或directory task都应指定`mode`,不得依赖`umask`。
- 为shell变量加引号并启用严格的shell error handling。
- 将静态分析抑制视为需要审查的例外,而不是捷径。
提交变更前,检查差异,记录已运行的检查,并确认持续集成将执行相同的必要验证。
## 尽早检查输入,不把密码和密钥放进代码库
在高成本操作或状态变更操作前验证输入。在最早的可靠位置拒绝空collection、缺失配置、格式错误的address、不兼容version以及permission不匹配。
- 明确设置file和directory的mode。
- permission、authentication、cryptography或security boundary出现错误时必须失败。警告只保留给真正可选的行为。
- 在错误中指出失败条件和安全的纠正操作,使错误可以直接处理。
- 应用最小权限原则:尽量减少permission、account、保留credential和process capability。
- 使用安全默认值、强cryptography、严格firewall rule、最少logging和最少data retention。
- 绝不能把password、private key、access token或provider credential放入source control。
- 发现并确认security vulnerability后立即响应,并验证升级后的行为。
- 避免未记录的workaround。记录workaround存在的原因并引用其上游issue,以便维护者日后安全停止使用。
添加task、conditional、provider path或module前,先在codebase中搜索已确立的pattern。除非有证据表明不适用,否则复用既有control flow。
## 避免 Ansible loop 和 Jinja2 template 中的常见错误
不要机械地把旧式iteration替换为`loop`。某些旧式iteration会展平嵌套list,而`loop`会保留其结构。验证产生的item shape,并确认预期的file或resource确实被创建。
- 把list直接传给`loop`;不要再用另一个list包裹已有list。
- 如果旧构造会展平多个input,应明确合并这些list。
- path变量末尾不要保留slash,以避免separator重复。
- 对只读command和handler设置`changed_when: false`,确保state report准确。
- 只有command失败已明确预期且安全时才使用`failed_when: false`;不要隐藏无关失败。
在Jinja2 native evaluation下:
- 条件必须使用实际boolean,而不是`"true"`或`"false"`等string。
- 把变量直接传给lookup;不要在template expression中嵌套另一个template expression。
- lookup返回file content时,应明确parse JSON text。
- 请注意,除非启用falsy value option,否则`default()`不会替换空string。
- 用普通automation loop和明确累积替代复杂的template生成list comprehension。
- boolean predicate使用test,data transformation使用filter。
使用自动化框架的真实filter或忠实mock测试template。仅凭语法有效不能证明native mode下的行为正确。
## 从监听端口开始,逐层排查网络服务问题
从最低的未知层开始调试network automation,不要假定所有连接症状都是routing failure。
1. 确认预期的TCP和UDP socket正在指定address和port上listen。
2. 检查service和socket unit状态中是否有配置警告。
3. 验证必要的kernel network setting。
4. 直接针对配置的resolver测试name resolution。
5. 只有完成以上步骤后,才检查firewall、address translation和policy routing rule。
对于socket activation服务,应配置socket unit,而不是只修改service配置。必要时先清除继承的listener,同时定义stream和datagram listener,并在变更后重启socket。禁用socket可能破坏service dependency。
有意识地处理platform差异:
- firewall backend可能重新排列rule;应固定或验证自动化所预期行为对应的backend。
- 多网络连接host进行address translation时,可能需要明确指定outbound interface。
- 如果能够满足要求,优先使用明确interface的简单masquerading,不要引入不必要的source translation复杂度。
- 检测已安装tool version后,再按条件添加compatibility flag。
- 当host和port语法要求时,用bracket括起IPv6 endpoint。
- 重新设计routing或translation rule前,先检查name resolution。
保持network rule简单,并测试packet flow,不要根据task result推断成功。
## 证明回归测试在缺陷重新出现时确实会失败
回归测试必须证明它确实能够检测其声称要防止的缺陷。
1. 为失败场景编写聚焦测试。
2. 暂时引入缺陷或改变相关条件。
3. 确认新测试因预期原因而失败。
4. 恢复正确实现并确认测试通过。
5. 记录该测试防止的确切回归。
当行为取决于template、file path、permission、firewall rule或collection shape时,应测试可观察结果,而不只是生成text。根据情况验证已创建file、实际mode、parse后的value、listener state、packet flow或render结果。
变更影响path或行为时,应更新现有测试。测试对失败的敏感性得到证明之前,不要假定一个通过的测试具有实际意义。
## 让部署无需人工输入即可运行,只报告实际做过的检查
面向持续集成或agent的automation必须支持完全无交互的执行路径。
- 通过已批准的parameter或environment variable预定义对应变量时,必须绕过所有prompt。
- 记录完整的核心变量集合,包括其type、default和purpose。
- 将provider专用credential与普通配置分离,并且只允许通过已批准的secret channel接收。
- local或高影响deployment mode必须使用明确的confirmation variable。
- 为optional feature提供明确的boolean value,避免headless run因缺少input而暂停。
- 在具有代表性多interface、多address条件的clean environment中测试无交互路径。
完成前,运行所有linter、syntax check、相关unit test以及全新deployment或等效integration test。检查差异中是否存在无关修复、无依据的dependency、隐藏suppression、缺失file mode、secret和未记录行为。报告收集到的确切证据;如果只执行了静态检查,不得声称deployment成功。
