AWS_CDK、Troposphere 与 Stacker:AWS 资源配置如何选型?
新项目优先评估 AWS CDK,已有体系按缺口选择
如果新项目只面向 AWS,没有语言限制,又希望复用基础设施组件、减少部署脚本,建议优先评估 AWS CDK v2。它将资源抽象、模板生成、变更预览、资产发布和部署整合在同一套工具链中。
已有基础设施体系的团队,可以按具体需求选择:
- 已有 CloudFormation 部署流水线,希望用 Python 生成便于审查的模板,可以选择 Troposphere。
- 已采用 Troposphere 或已有 Python Blueprint,需要补上多栈依赖、环境配置和部署编排,可以评估 Stacker。
“CDK 仍处于 developer preview”是提问时的历史背景,已不适合作为当前选型的依据。CDK v2 已有稳定 API,也保留了实验性模块,采用前需要分别确认。若讨论的是当年的决策,则应按当时的功能和稳定性判断。AWS CDK 版本说明
模板生成、部署编排和状态管理
三个工具负责的工作有所不同:
| 工具 | 主要职责 | 需要自行补充的部分 |
|---|---|---|
| AWS CDK | 用代码定义资源,合成模板,并通过 CLI 部署;提供可复用的 constructs | CI 平台配置、权限、审批、部署后验证 |
| Troposphere | 用 Python 构建 CloudFormation 模板,并进行部分属性和类型检查 | 变更预览、部署、资产上传、多栈编排等流程 |
| Stacker | 创建和更新多个 CloudFormation 栈,管理依赖及环境配置;Blueprint 通常使用 Troposphere | CI 平台配置、组织级发布策略和验证 |
Troposphere 与 Stacker 可以组合使用。Stacker 的 Blueprint 通常用 Troposphere 编写,也支持直接读取 JSON/YAML 模板。Troposphere 项目说明、Stacker 模板支持
状态由谁维护?
在常规 CloudFormation 部署流程中,CloudFormation 负责维护栈模板、资源标识映射和操作状态。使用 Troposphere 无需另外实现一套资源状态存储,但需要补上部署管理功能。
这里需要区分三个问题:
- 代码希望部署什么:由 CDK 或 Troposphere 生成模板。
- 相对已部署模板准备修改什么:通过模板比较或 CloudFormation Change Set 预览。
- 实际资源是否被手工修改过:通过漂移检测检查。
cdk diff 主要处理第二个问题。它可以借助 Change Set 判断资源替换情况,但不能替代实际资源的漂移检测。cdk diff 文档
例如,有人在控制台修改了资源,而代码和已部署模板都没有变化,此时就需要检查漂移(drift)。CloudFormation 的漂移检测只覆盖支持的资源和属性,通常只检查模板或参数中显式设置的值。CloudFormation 漂移检测
从开发和维护角度如何权衡?
| 维度 | AWS CDK | Troposphere | Stacker |
|---|---|---|---|
| 抽象与复用 | L1、L2、L3 constructs,可封装组织内部组件 | 贴近 CloudFormation;通过 Python 函数、类和模块自行封装 | 通过 Blueprint 和配置复用模板及部署结构 |
| 开发实践 | 可使用语言工具链,并提供模板断言工具 | 可使用 Python 测试、代码检查和包管理工具 | 可测试 Blueprint,同时需要管理环境配置和依赖关系 |
| 代码维护 | 高层抽象减少重复配置;需要理解默认行为及合成结果 | 资源属性直观,便于对照 CloudFormation;组合逻辑需要自行维护 | 多栈结构集中管理;增加了编排工具及其配置的维护成本 |
| 资源支持 | 先检查 L2/L3,再检查 L1 和底层覆盖能力 | 检查所安装版本是否包含目标资源与属性 | 使用 Blueprint 时取决于相关库;直接模板取决于 CloudFormation |
| CI/CD | CLI 和 CDK Pipelines 提供较完整的部署路径 | 接入 AWS CLI、SDK 或现有流水线 | diff、build 可作为流水线中的部署步骤 |
CDK 提供不同层次的 constructs:
- L1 通常直接对应 CloudFormation 资源,例如
CfnBucket。 - L2 提供默认配置和辅助方法,例如
Bucket。 - L3 将多个资源组合为一种架构模式。
某项服务缺少高层 construct 时,可以继续检查 L1,不能据此判断 CDK 无法配置该服务。高层抽象也可能生成额外资源和权限,因此审查时仍要查看合成模板。AWS CDK constructs
Troposphere 也可以构建抽象,组合方式和默认策略主要由团队决定。对于已有内部 Python 组件库的团队,这种控制方式可能更合适。
Stacker 主要负责多栈编排,能根据依赖安排部署顺序,并把一个栈的 Outputs 传入另一个栈。它也提供 diff,文档中的实现通过 Change Set 展示变更,但对跨栈输出变化的推断存在限制。Stacker 功能说明、Stacker 命令说明
资源支持应检查具体属性
选型时,除了比较支持多少种 AWS 服务,还应列出必需的资源,逐项检查:
- 目标 Region 的 CloudFormation 是否支持该资源和属性。
- 所选工具版本是否已经暴露这些属性。
- 缺少高层接口时,能否使用底层接口或直接模板。
- 必须使用 Custom Resource 时,谁负责其权限、更新、删除和失败恢复。
Stacker 的部署编排功能不会扩大 CloudFormation 的原生资源覆盖范围,CDK 的 L2/L3 也不能保证覆盖每个新属性。
CI/CD 应如何落地?
Troposphere 需要额外的自动化来完成部署。已有成熟 CloudFormation 流水线时,它只需提供模板;AWS CLI 可以创建 Change Set、执行变更,并在需要时上传模板,部署流程未必复杂。
CDK 可以减少这些环节的拼接工作。CDK Pipelines 还支持用代码定义流水线,不过凭证、部署角色、审批和环境隔离仍需要配置。CDK Pipelines
实施时可按以下顺序进行:
- 固定依赖版本,执行代码检查和必要的模板断言。
- 生成并保存模板、资产及环境参数,作为可追溯的构建制品。
- 生成变更预览,检查删除、替换和 IAM 权限变化。
- 根据发布策略审批,部署已审核的制品,等待栈操作完成。
- 执行部署后验证,并按计划检查漂移。
CDK 的 assertions 模块可以检查合成模板中的资源属性,Troposphere 和 Stacker 也可以测试生成结果。测试应重点检查权限、加密、保留策略等约束,单靠模板快照无法证明部署正确。AWS CDK 测试指南
代码示例:三种部署路径
三个示例都定义了一个启用版本控制、阻止公共访问并保留数据的 S3 Bucket。三条路径应分别评估,不应依次用于接管同一个既有栈。
运行前需要安装对应依赖,并配置 AWS 凭证及目标 Region。
AWS CDK:定义并部署
使用 CDK v2 的 Python 包 aws-cdk-lib 和 constructs,将代码保存为 app.py:
from aws_cdk import App, RemovalPolicy, Stack
from aws_cdk import aws_s3 as s3
app = App()
stack = Stack(app, "DataStack")
s3.Bucket(
stack,
"DataBucket",
versioned=True,
block_public_access=s3.BlockPublicAccess.BLOCK_ALL,
removal_policy=RemovalPolicy.RETAIN,
)
app.synth()
通过已安装的 CDK CLI 执行:
cdk bootstrap
cdk synth DataStack --app "python app.py"
cdk diff DataStack --app "python app.py"
cdk deploy DataStack --app "python app.py"
cdk bootstrap 为目标账户和 Region 准备部署所需的资源,例如资产存储桶和 IAM 角色。生产环境应审查这些角色的权限。CDK bootstrapping、S3 Bucket API
Troposphere:生成模板,再交给部署工具
将代码保存为 template.py:
from troposphere import Template
from troposphere import s3
template = Template()
template.add_resource(
s3.Bucket(
"DataBucket",
VersioningConfiguration=s3.VersioningConfiguration(
Status="Enabled"
),
PublicAccessBlockConfiguration=s3.PublicAccessBlockConfiguration(
BlockPublicAcls=True,
BlockPublicPolicy=True,
IgnorePublicAcls=True,
RestrictPublicBuckets=True,
),
DeletionPolicy="Retain",
UpdateReplacePolicy="Retain",
)
)
print(template.to_json())
用 AWS CLI 补上 Troposphere 自身不提供的变更预览和部署环节。先生成模板,再创建待审核的 Change Set:
python template.py > template.json
aws cloudformation deploy \
--template-file template.json \
--stack-name DataStack \
--no-execute-changeset
--no-execute-changeset 会在创建 Change Set 后退出。审核后,应使用 execute-change-set 执行同一个 Change Set,流水线还需等待栈操作完成。较大的模板需要通过 --s3-bucket 指定已有的模板存储桶。AWS CLI cloudformation deploy
Stacker:复用模板并增加编排
也可以把上述 template.json 交给 Stacker。环境文件 dev.env:
namespace: faq-dev
配置文件 stacker.yaml:
stacks:
- name: data
template_path: template.json
执行:
stacker diff -r us-east-1 dev.env stacker.yaml
stacker build -r us-east-1 -i dev.env stacker.yaml
将 us-east-1 替换为目标 Region。-i 启用交互式 Change Set 审核;无人值守流水线应设置独立的审批步骤,不依赖终端输入。具体行为以所安装版本的帮助信息为准。Stacker 命令参考
选型前还要验证什么?
先选一组有代表性的资源做验证,覆盖跨栈引用、IAM 权限、代码资产,以及一个有数据保留要求的资源。验证范围应包括首次创建、属性更新、资源替换、失败回滚和代码重构。
还需要检查以下问题:
- CloudFormation 使用逻辑 ID 跟踪资源。在 Troposphere 中修改资源标题,或在 CDK 中调整 construct ID、路径,都可能影响资源身份。重构后必须检查变更预览。CDK 标识符说明
- CDK 项目应保存影响合成结果的配置和 context;其他方案中的环境参数、动态 lookup 也需要保证可追溯。
Retain能保护资源免于某些删除操作,但仍需要备份和恢复方案。- 引入 Stacker 等额外依赖前,应检查其发布记录、目标 Python 运行时及依赖兼容性。仅凭文档可以访问,无法判断维护状态是否符合团队要求。
- 已有稳定的 Troposphere 或 Stacker 体系时,应先确认迁移能解决哪些具体成本,再决定是否切换。
备注:内容仅供参考。
