策略即代码一直有个别扭的依赖:规则用一种团队里没几个人能流畅阅读的语言写成,于是这道闸门在计划阶段很强,在评审阶段却很模糊。HashiCorp在2026年11月5日给出的答案是,把规则搬进HCL,并让模型来做翻译。

打开网易新闻 查看精彩图片

这次发布的Terraform policy agent,负责把Sentinel和OPA策略转换成Terraform policy。转换本身值得细看,因为它暴露了一个所有自动化迁移都要面对的问题:机器生成的代码,谁来担保它和原来一样。

这道闸门同时接受三套框架

Terraform policy是HashiCorp推出的声明式框架,用HCL写规则,决定一份Terraform计划能否继续推进,HCP Terraform在运行过程中评估这些规则。同一道闸门接受Terraform policy、Sentinel和Open Policy Agent三套框架。

真正促使团队迁移的是一个覆盖范围上的差别:只有Terraform policy的policy set同时适用于Stacks和workspaces,Sentinel和OPA的policy set只支持workspaces。对于已经或正在迁往Stacks的团队来说,留在旧框架里的策略库,看不见自己新建的那道闸门。

策略以policy set为单位组织,一个set只能装同一套框架写的策略,来自不同框架的多个set可以作用于同一个workspace或Stack。策略失败能否中止运行,取决于它的执行级别;具备相应权限的身份可以执行覆盖。Terraform policy要求Terraform v1.17或更高版本。

转换分三步,第一步不写代码

agent的输入可以是一个Sentinel的.sentinel文件、一个OPA的.rego文件、一组文件,或者整个策略仓库,它从每条策略的意图出发工作。整个过程分三个阶段:

  1. 提取策略目标,转写成普通人能读懂的纯语言需求,这是在任何代码产生之前就交付的评审材料;
  2. 生成.policy.hcl文件、.policytest.hcl文件、配套的Terraform配置,以及一份转换报告;
  3. 运行生成的测试,按策略汇总结果。

第一步是个值得借鉴的设计决定。转换先给出一段可读的说明,讲清这条策略是干什么的,评审者就能在成本最低的时候提出异议。

测试生成还会读取Sentinel的mock文件。在生成第一批测试场景之后,agent会补充这些场景尚未覆盖的用例。已有的mock是策略库里最接近回归测试的东西,把它当作覆盖来源,生成的测试才值得跑。

这个做法也划出了上限。mock描述的是团队当初写策略时想到的场景,没有mock覆盖的行为依然不可见。一条通过了全部生成测试的转换策略,可能在策略库从未编码的那个边界上表现得完全不同。

关于等价,公告自己划了线

发布公告里有一句少见的坦白:输出由语言模型生成,不同次运行的结果可能不同。通过生成的测试,只能说明这条策略满足了生成的场景;与原始Sentinel或OPA策略是否等价,公告没有替你做这个结论,它把这件事留给了评审者。

这句话要放在策略库的寿命里读。一个Sentinel库是一份决策记录,里面装着各种别扭的东西:遗留账号的例外、迁移期间临时放行的区域、绑定在未成文命名约定上的标签规则。从意图出发的转换,会产出一条执行该意图的策略,而那些例外怎么处理,仍然需要人来核对。

公告建议的上线顺序是:对每条转换后的策略运行tfpolicy test,把结果放进HCP Terraform并设为advisory执行级别,等行为验证之后再转为mandatory。这个顺序的理由很直接——一条会阻断计划的策略就是一台生产事故制造机,而转换后的策略,按任何合理定义都算新代码。

advisory阶段只有在有人读它报告什么的时候才产生价值。把转换后的库跑在advisory级别,将它的失败与旧框架的决策逐条比对,团队才能在转为强制之前拿到关于这次转换的证据。

需要盯住的漂移有几种:静默放宽,让转换后的策略放行了原策略排除的情况;静默收窄,拦下过去能通过的部署,逼得团队在第一周就放松规则;例外丢失,旧库里有明确记录的豁免没有带过来,新库对着一个没人预警的工作负载执行了通用规则。

还有一点:agent产出的任何东西都不会自动发布到HCP Terraform。策略库要进入那道闸门,得有人亲手把它放进去。