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。
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 只适用于安全场景——它同样适用于成本控制、命名规范、标签合规等运维治理领域。
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 计划文件。若返回非空数组,则阻断部署。