2. Pulumi 堆栈状态:State 文件结构、State 与真实云资源的关系、State 的存储后端
Pulumi State(状态文件)是基础设施即代码的核心资产。它记录了 Pulumi 堆栈所管理的所有云资源的唯一标识、属性、依赖关系以及元数据。理解 State 的结构、它与真实云资源的关系以及存储后端的选择,是掌握堆栈漂移检测与复核流程的基础。
2.1 Pulumi State 文件结构
Pulumi 的 State 文件本质上是一个经过版本化、结构化的 JSON 文档。它不直接存储云资源的全部属性,而是存储 Pulumi 引擎用于跟踪和协调资源所需的“资源对象”快照。
一个典型的 State 文件顶层结构包含以下关键字段:
| 字段 | 类型 | 说明 |
|---|---|---|
version |
整数 | State 文件格式版本号,用于向后兼容。 |
deployment |
对象 | 包含部署快照的核心容器,内部包含 resources 数组。 |
resources |
数组 | 由 Pulumi 管理的所有资源对象的列表,是 State 文件的主体。 |
checkpoint |
字符串 | (可选)用于增量检查点的元数据。 |
每个 resource 对象的结构如下:
{
"urn": "urn:pulumi:production::my-project::aws:s3/bucket:Bucket::my-app-data",
"type": "aws:s3/bucket:Bucket",
"id": "my-app-data-2024",
"inputs": {
"bucket": "my-app-data-2024",
"acl": "private"
},
"outputs": {
"bucket": "my-app-data-2024",
"arn": "arn:aws:s3:::my-app-data-2024",
"bucketDomainName": "my-app-data-2024.s3.amazonaws.com"
},
"parent": "urn:pulumi:production::my-project::aws:s3/bucket:Bucket::my-app-data",
"dependencies": [
"urn:pulumi:production::my-project::aws:iam/role:Role::app-role"
],
"provider": "urn:pulumi:production::my-project::pulumi:providers:aws::default_6_50_0"
}
关键字段解析:
- urn:全局唯一资源名称,由堆栈名、项目名、资源类型和逻辑名称组成,是 State 中资源的唯一标识。
- id:云服务商分配给该资源的物理 ID(如 AWS 的物理 ID、Azure 的资源 ID)。
- inputs:用户代码中定义的期望配置。
- outputs:云服务商返回的实际属性值,包含计算出的属性(如 ARN)。
- dependencies:该资源依赖的其他资源的 URN 列表,用于构建资源图。
2.2 State 与真实云资源的关系
Pulumi State 文件不是云资源的完整副本,而是一个“期望状态”与“已知实际状态”的混合体。理解这种关系对于漂移检测至关重要。
核心关系要点:
- URN 到物理 ID 的映射:State 通过 URN 关联逻辑资源,通过
id字段关联物理资源。漂移发生时,物理 ID 不变,但属性可能变化。 - Inputs vs Outputs:
inputs是用户代码中的期望值,outputs是云服务商返回的实际值。当两者不一致时,可能表示漂移或资源更新。 - State 不是实时同步的:State 仅在
pulumi up、pulumi refresh或pulumi import等操作时更新。云控制台的手动修改不会自动反映到 State 中。
2.3 State 的存储后端
Pulumi 支持多种 State 存储后端,选择正确的后端对于团队协作、安全性和灾难恢复至关重要。
| 后端类型 | 存储位置 | 适用场景 | 关键特性 |
|---|---|---|---|
| Pulumi Cloud | SaaS 平台 | 团队协作、CI/CD 集成 | 内置版本历史、审计日志、访问控制、漂移检测 |
| 自托管(Self-Managed) | 用户指定的存储 | 合规要求、离线环境 | 支持 AWS S3、Azure Blob、GCP GCS、本地文件系统 |
| 本地文件系统 | 本地磁盘 | 个人开发、快速原型 | 无需网络,但无法共享,有丢失风险 |
2.3.1 自托管后端配置示例
使用 AWS S3 作为 State 后端时,需要在项目配置中指定:
# Pulumi.yaml 或通过 pulumi stack init 指定
pulumi stack init production --secrets-provider="awskms:///arn:aws:kms:us-east-1:123456789012:key/abc123"
# 设置后端为 S3
pulumi login s3://my-pulumi-state-bucket/production/
自托管后端支持以下存储选项:
- AWS S3:需要配置 IAM 权限(
s3:PutObject、s3:GetObject、s3:DeleteObject、s3:ListBucket)。 - Azure Blob Storage:使用
azurerm://前缀,需要存储账户密钥或 SAS 令牌。 - Google Cloud Storage:使用
gs://前缀,需要服务账号权限。 - 本地文件系统:使用
file://前缀,仅用于开发环境。
安全警告:State 文件可能包含敏感信息(如数据库密码、),即使使用了 Secrets 加密,State 文件本身也应被视为敏感资产。对于自托管后端,务必启用:
- 存储桶加密(SSE-S3、SSE-KMS 或 Azure 加密)
- 访问日志记录
- 版本控制(防止误删除或覆盖)
- 严格的 IAM 策略(最小权限原则)
2.3.2 后端选择对比
最佳实践建议:
- 生产环境:优先使用 Pulumi Cloud,获得内置的漂移检测、审计日志和团队协作功能。
- 合规敏感环境:使用自托管 S3/GCS/Azure Blob,配合 KMS 加密和严格的 IAM 策略。
- CI/CD 流水线:确保流水线有权限访问 State 后端,并配置 Secrets 提供者(如 AWS KMS、Azure Key Vault)。
- 避免本地文件系统:仅用于快速原型开发,不要用于任何共享或生产环境。