基础设施即代码(IaC)基础
2.1 IaC 的定义与核心价值
基础设施即代码(Infrastructure as Code, IaC) 是一种通过机器可读的定义文件(而非手动配置)来管理和配置计算基础设施的实践。其核心理念是将服务器、网络、数据库等基础设施资源视为软件代码,纳入版本控制、自动化测试与持续交付流水线。
核心价值:
- 可重复性:消除环境漂移,每次部署生成一致的基础设施。
- 版本控制:所有变更可追溯、可回滚,支持代码审查与协作。
- 自动化:减少手动操作错误,加速资源交付周期。
- 自文档化:代码即文档,降低知识传递成本。
- 可测试性:可在沙箱环境中验证基础设施变更,提前发现配置错误。
2.2 声明式与命令式 IaC 对比
IaC 工具按描述方式分为两大范式:声明式(Declarative) 和 命令式(Imperative)。理解两者的差异是选择工具和编写可靠代码的基础。
| 对比维度 | 声明式(Declarative) | 命令式(Imperative) |
|---|---|---|
| 核心思想 | 描述目标状态(What) | 描述执行步骤(How) |
| 幂等性 | 天然幂等,重复执行结果一致 | 需手动保证幂等,易产生漂移 |
| 可读性 | 高,关注最终配置 | 低,需理解执行顺序 |
| 状态管理 | 工具自动跟踪状态 | 依赖脚本逻辑或外部状态文件 |
| 典型工具 | Terraform, CloudFormation, Pulumi (YAML) | Ansible (Playbook), Chef (Recipe), Shell 脚本 |
| 适用场景 | 云资源编排、长期运行的基础设施 | 配置管理、一次性任务、复杂条件逻辑 |
实践建议:在 Policy Check 集成场景中,推荐优先使用声明式工具。声明式代码的幂等性使得策略检查可以在
plan 阶段(而非 apply 后)拦截违规变更,显著降低安全风险。
2.3 主流 IaC 工具简介
当前业界最主流的声明式 IaC 工具包括 Terraform、AWS CloudFormation 和 Pulumi。下表从多维度进行对比:
| 特性 | Terraform | AWS CloudFormation | Pulumi |
|---|---|---|---|
| 提供商 | HashiCorp | AWS | Pulumi Corp |
| 语言 | HCL (HashiCorp Configuration Language) | JSON / YAML | 通用编程语言 (TypeScript, Python, Go, C#, Java) |
| 多云支持 | ✅ 广泛(AWS, Azure, GCP, 私有云等) | ❌ 仅 AWS | ✅ 广泛(与 Terraform 类似) |
| 状态管理 | 独立状态文件(本地或远程 Backend) | AWS 托管(Stack 状态) | 独立状态文件(支持自托管或 Pulumi Cloud) |
| 模块/复用 | Registry 模块,版本化 | 嵌套 Stack,资源导入 | 编程语言包管理(npm, pip, go mod) |
| 策略集成 | Sentinel / OPA / 自定义 Provider | AWS Config / Service Catalog | CrossGuard (OPA / 自定义策略) |
| 学习曲线 | 中等(HCL 语法简单) | 中等(JSON/YAML 冗长) | 较高(需掌握编程语言) |
2.4 工具选型与 Policy Check 集成考量
在《Policy Check 集成 IaC 部署门禁》课程中,工具选型直接影响策略引擎的集成方式。以下是关键考量:
- Terraform + OPA/Sentinel: 最成熟的组合。Terraform 的
plan阶段可输出 JSON 格式的变更计划,OPA 或 Sentinel 可对其进行策略评估,实现“事前拦截”。 - Pulumi + CrossGuard: 利用通用编程语言的表达能力,策略可以写成函数或类,集成更灵活,适合需要复杂逻辑判断的合规场景。
- CloudFormation + AWS Config: 适合纯 AWS 环境,但策略检查通常在部署后(事后检测)进行,与“部署门禁”的实时拦截理念略有差异。
注意: 无论选择哪种工具,都应确保策略检查在 部署执行前 完成。对于 Terraform,这意味着在
terraform apply 之前运行 terraform plan 并触发策略引擎;对于 Pulumi,则是在 pulumi up 的 preview 阶段进行。
2.5 代码示例:Terraform 声明式定义
以下是一个简单的 Terraform 代码片段,声明一个 AWS S3 存储桶并启用版本控制。注意代码只描述“最终状态”,而非创建步骤。
# main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "example" {
bucket = "my-policy-check-demo-bucket"
tags = {
Environment = "Dev"
ManagedBy = "Terraform"
}
}
resource "aws_s3_bucket_versioning" "example" {
bucket = aws_s3_bucket.example.id
versioning_configuration {
status = "Enabled"
}
}
关键点: 上述代码中,
aws_s3_bucket_versioning 资源显式声明了版本控制为 Enabled。在 Policy Check 场景中,策略可以检查 plan 输出中是否包含 versioning_configuration.status = "Enabled",若缺失则拒绝部署。