4. Policy as Code (PaC) 概念

Policy as Code(策略即代码,PaC)是将基础设施与应用的合规、安全、运维规则以机器可读的代码形式进行声明、存储、执行与审计的工程实践。PaC 是基础设施即代码(IaC)在治理层面的自然延伸,它让“规则”像“资源”一样被版本化、自动化与可重复验证。

4.1 PaC 的定义

PaC 的核心思想是:用代码定义策略,用引擎执行策略,用日志证明合规。传统策略通常以 PDF、Wiki 或人工检查清单的形式存在,而 PaC 将其转化为结构化的策略文件(如 Rego、OPA 策略、Sentinel 策略、CUE 约束等),并集成到 CI/CD 流水线中。

关键特征:
  • 声明式:策略描述“应该是什么”,而非“如何检查”。
  • 机器可读:策略文件可被自动化工具解析、评估与报告。
  • 版本化:策略随代码库一起管理,支持 diff、回滚与协作。
  • 可测试:策略本身可以编写单元测试,确保规则逻辑正确。

4.2 PaC 与 IaC 的关系

IaC 定义了“基础设施应该长什么样”,PaC 定义了“基础设施应该遵守什么规则”。两者在 DevOps 流水线中形成互补关系:

维度 基础设施即代码 (IaC) 策略即代码 (PaC)
关注点 资源定义与配置(VPC、ECS、RDS) 合规约束与安全规则(端口、加密、标签)
工具示例 Terraform、CloudFormation、Pulumi OPA/Rego、Sentinel、Kyverno、CUE
执行时机 计划(plan)与应用(apply)阶段 计划前(pre-plan)或计划后(post-plan)门禁
输出产物 基础设施状态文件 合规报告、拒绝/允许决策
变更影响 直接变更云资源 阻止或允许变更执行
实践建议:在 CI/CD 流水线中,PaC 通常作为 IaC 的“前置门禁”或“后置校验”存在。例如:Terraform plan 生成 JSON 计划文件 → OPA 策略引擎评估该计划 → 若违反策略则阻断 apply。
PaC 与 IaC 在 CI/CD 流水线中的协作关系 PaC 与 IaC 在 CI/CD 流水线中的协作关系 代码提交 IaC Plan PaC 策略门禁 IaC Apply 拒绝(阻断) 流程说明: 1. 开发者提交 IaC 代码(Terraform / Pulumi 等)。 2. 流水线执行 terraform plan 生成资源变更计划(JSON)。 3. PaC 引擎(如 OPA)评估计划文件: - 通过 → 允许执行 terraform apply;- 拒绝 → 阻断流水线并返回违规报告。

4.3 PaC 的核心优势

将策略代码化并集成到部署门禁中,为团队带来三个核心价值:自动化、可审计、一致性。

4.3.1 自动化

  • 零人工干预:策略评估在 CI/CD 流水线中自动触发,无需安全工程师逐条人工审核。
  • 即时反馈:开发者在提交代码后数秒内即可获得合规检查结果,缩短反馈循环。
  • 批量执行:一次策略更新可同时应用于所有历史与未来的部署请求。

4.3.2 可审计

  • 完整变更历史:策略文件存储在 Git 仓库中,每次修改都有 commit 记录、作者与时间戳。
  • 决策可追溯:每次策略评估的输入(IaC 计划)、输出(通过/拒绝)与规则版本均可记录为审计日志。
  • 合规报告自动生成:可基于历史评估数据生成周期性合规报表,满足 SOC2、PCI-DSS 等审计要求。

4.3.3 一致性

  • 消除人为偏差:不同环境(开发、测试、生产)执行同一套策略代码,避免“人工审核标准不一”。
  • 环境无差别执行:策略引擎在本地、CI 与生产环境行为一致,杜绝“在我机器上能通过”的问题。
  • 策略即文档:代码化的策略本身就是最精确的合规文档,不会出现“文档写 A、实际查 B”的偏差。
常见误区:PaC 不是 IaC 的替代品,而是 IaC 的治理层。不要试图用 PaC 去定义资源(那是 IaC 的工作),也不要认为 PaC 只适用于安全场景——它同样适用于成本控制、命名规范、标签合规等运维治理领域。
Policy as Code 三大核心优势 Policy as Code 三大核心优势 Policy as Code 自动化 零人工干预 · 即时反馈 可审计 变更历史 · 决策追溯 一致性 消除偏差 · 环境无差别 三者共同构成 PaC 的工程价值:自动化提升效率,可审计满足合规,一致性保障质量。

4.4 典型 PaC 策略示例(OPA / Rego)

以下是一个简单的 OPA 策略,用于检查 Terraform 计划中是否禁止开放所有端口(0.0.0.0/0)的安全组规则:

# 策略文件: deny_public_ingress.rego
package terraform.analysis

# 禁止安全组入站规则允许 0.0.0.0/0
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_security_group_rule"
    resource.change.after.type == "ingress"
    resource.change.after.cidr_blocks[_] == "0.0.0.0/0"
    msg := sprintf("安全组规则 %v 禁止开放 0.0.0.0/0 入站", [resource.address])
}
执行方式:在 CI 流水线中,使用 opa eval --format json --data policy.rego --input plan.json "data.terraform.analysis.deny" 命令评估 Terraform 计划文件。若返回非空数组,则阻断部署。