cdk
1. 基础环境安装
以node.js为运行环境:npm install -g aws-cdk,cdk –version
还需要有aws-cli运行环境:https://aws.amazon.com/cn/cli/,https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html
初始化cdk项目
1 | mkdir cdk-python-test && cd cdk-python-test |
2. 基础概念
2.1 AWS CDK L1 / L2 / L3 层级 最全详解
前置说明:
L = Level,层级的意思;这三层都是 AWS CDK 中创建 AWS 云资源的方式,本质都是帮你生成 AWS CloudFormation 模板,只是封装程度、开发效率、灵活性完全不同。
2.2 核心总纲
L1 < L2 < L3 ,封装程度越来越高、代码量越来越少、开发效率越来越高、灵活性越来越低
- L1:最底层、最灵活、最繁琐,完全对应原生 CloudFormation
- L2:最常用、首选、99% 的开发场景都用它,AWS 官方封装的高级 API,平衡效率和灵活度
- L3:最高层、最便捷、封装到极致,官方预制的「完整业务场景解决方案」,开箱即用
2.3 为什么会有 L1/L2/L3 三层?
AWS CDK 的核心是 「基础设施即代码 (IaC)」,最终执行cdk synth后,都会生成一份标准的 AWS CloudFormation(CFN)模板(JSON/YAML),再由 CFN 帮你在 AWS 账号中创建 / 更新 / 删除资源。
而这三层的本质,就是 CDK 对「CFN 资源定义」的 三层封装:
CFN 是 AWS 的底层资源编排引擎 → L1 是 CFN 的直译 → L2 是 L1 的封装优化 → L3 是 L2 的组合封装
类比:你要做番茄炒蛋 → L1 是 “自己种番茄、养鸡取蛋、切菜、炒蛋” → L2 是 “超市买切好的番茄 + 盒装蛋液,直接炒” → L3 是 “买预制番茄炒蛋,加热即食”
2.4 分层详解
所有代码案例都是创建 AWS S3 存储桶
2.4.1 L1 - 底层构造:CFN 原生资源 (CFN Resources)
2.4.1.1 定义
官方命名:CfnXXX → 所有 L1 资源类名全部以 Cfn 开头(CloudFormation 的缩写),这是识别 L1 的绝对标志。
核心定义:CDK 对 AWS CloudFormation 模板的「1:1 直译、无任何封装」。AWS 有多少个 CFN 资源类型,CDK 就有多少个对应的 L1 类,所有属性、参数、配置项,和 CFN 模板里的字段完全一致、一字不差。
核心特点:
优点:极致灵活、无任何限制,能实现 AWS 所有资源的所有配置,包括一些极冷门的底层属性,L2/L3 做不到的配置都能靠 L1 实现。
缺点:超级繁琐、开发效率极低、极易出错,需要你完全熟记 CFN 模板的字段名,代码量巨大,还要手动处理所有依赖关系(比如创建 EC2 需要先创建子网)。
数据特点:L1 的属性值,全部是原始字符串 / 数字,没有类型校验、没有默认值、没有自动填充,填错一个字段名就会部署失败。
2.4.1.2 代码案例
1 | // 导入L1的S3桶构造器,类名固定:CfnBucket |
2.4.1.3 使用场景
- 你需要配置某个 AWS 资源的 极冷门的底层属性,而这个属性在 L2/L3 中没有暴露出来;
- AWS 刚发布了新的服务 / 新的资源属性,L2/L3 还没来得及更新封装,只能先用 L1;
- 极少数需要极致定制化的场景,比如深度定制 CloudFormation 的高级功能。
结论:日常开发尽量少用 L1,除非迫不得已。
2.4.2 L2 - 主力构造:AWS 托管资源 (AWS Resources)
2.4.2.1 定义
官方命名:XXX → 所有 L2 资源类名无任何前缀,比如 S3 桶就是 Bucket,EC2 实例就是 Instance,Lambda 函数就是 Function,这是识别 L2 的绝对标志。
核心定义:AWS 官方基于 L1 封装的「高级 API」,是 CDK 的核心和主力,也是 AWS CDK 团队投入最多精力维护的部分。L2 对 L1 做了大量的 人性化优化、封装、增强,本质上 L2 的底层依然是调用 L1 实现,只是帮你做了所有脏活累活。
核心特点:
优点 1:极简开发,代码量骤减 - 大量属性提供合理的默认值,不用手动配置基础属性,比如创建 S3 桶默认就是私有、开启加密、自动生成唯一桶名;
优点 2:强类型校验 - 所有属性都是 TS 强类型,写错字段名 / 属性值,写代码时就会报错,不用等到部署时才发现问题;
优点 3:自动处理依赖关系 - 比如创建 Lambda 需要依赖 IAM 角色,L2 会自动帮你创建并绑定角色,不用手动写依赖;
优点 4:内置最佳实践 - 所有默认配置都遵循 AWS 的安全最佳实践,比如 S3 默认私有、IAM 权限最小化、自动开启加密;
优点 5:兼顾灵活性 - 既保留了常用的配置项,又提供了 addPropertyOverride() 方法,可以直接覆盖底层 L1 的属性,满足定制化需求;
优点 6:丰富的辅助方法 - 比如 S3 桶的 grantRead()、grantWrite(),一行代码就能给 IAM 用户 / 角色授权,不用手动写复杂的 IAM 策略。
缺点:极少数极冷门的底层属性没有暴露,需要结合 L1 补充配置。
2.4.2.2 代码案例
1 | # 文件名:cdk_python_test_stack.py |
对比 L1:L1 需要写十几行代码的配置,L2 一行代码就能实现,而且更安全、更不易出错!
2.4.2.3 使用场景
所有日常开发场景,无脑选 L2!
不管是创建 S3、EC2、Lambda、DynamoDB、API Gateway、VPC 等任何 AWS 资源,优先用 L2,这是 AWS 官方推荐的最佳实践,也是 CDK 的核心价值所在。
2.4.3 L3 - 顶层构造:预制组件 / 模式 (Construct Libraries / Patterns)
2.4.3.1 定义
官方命名
无固定命名规则,一般是 「业务场景化的类名」,比如 LambdaRestApi(创建 Lambda+API Gateway 的完整 RESTful API)、ApplicationLoadBalancedFargateService(创建 ECS Fargate+ALB 的完整服务),也叫 CDK Patterns/Constructs。
核心定义
AWS 官方 / 社区基于 L2 封装的「业务级预制组件」,是最高层级的封装,也被称为「**CDK 模式 (Patterns)**」。
L3 是把 多个关联的 L2 资源组合成一个完整的业务场景,比如:
创建一个「带负载均衡的 ECS 服务」需要:ALB+TargetGroup+ECS Cluster+ECS Service+IAM 角色 + 安全组 → L2 需要写几十行代码,L3 一行代码搞定。
创建一个「RESTful API 接口」需要:API Gateway+Lambda+IAM 角色 → L2 需要写多行代码,L3 一行代码搞定。
核心特点
优点 1:极致效率,开箱即用 - 一行代码 = 一套完整的业务解决方案,不用手动组合多个 L2 资源,不用处理资源间的依赖和关联,开发效率直接拉满;
优点 2:内置最佳实践 + 架构规范 - L3 的所有组件都遵循 AWS 的「Well-Architected」架构规范,比如高可用、容错、安全、性能优化,你不用懂底层架构细节,也能写出合规的代码;
优点 3:无冗余代码 - 完全屏蔽底层资源的细节,专注于业务逻辑,代码可读性极高。
缺点:灵活性最低,L3 封装的是「通用场景」,如果你的业务场景是高度定制化的(比如特殊的权限策略、特殊的资源配置),L3 可能无法满足,需要回退到 L2 手动组合。
2.4.3.2 代码案例
这个案例是创建一个能对外访问的 API 接口,底层需要创建:API Gateway + Lambda 函数 + IAM 角色 + 权限绑定,L2 需要写 10 + 行代码,L3 一行搞定:
1 | # 文件名:cdk_python_test_stack.py |
部署后,你会得到一个可直接访问的 HTTPS API 地址,所有底层资源都自动创建并配置好,这就是 L3 的威力!
2.4.3.3 使用场景
- 你的业务场景是 AWS 的通用架构模式:比如 Lambda+API Gateway、ECS+ALB、S3+CloudFront、DynamoDB+Lambda 等;
- 追求极致开发效率,不想手动组合多个 L2 资源;
- 对底层架构细节不熟悉,想直接复用 AWS 官方的最佳实践架构。
✅ 结论:能用 L3 的场景,优先用 L3,省下的时间可以专注于业务逻辑。
2.5 L1/L2/L3 核心对比表
| 层级 | 官方名称 | 类名特征 | 封装程度 | 代码量 | 开发效率 | 灵活性 | 核心优势 | 适用场景 |
|---|---|---|---|---|---|---|---|---|
| L1 | CFN 原生资源 | 以Cfn开头 |
无封装(1:1 直译) | 多 | 极低 | ✅极致灵活 | 能实现所有配置 | 冷门属性、新功能、定制化底层需求 |
| L2 | AWS 托管资源 | 无任何前缀 | 高度封装(推荐) | 中 | ✅极高 | ✅平衡灵活与效率 | 强类型、默认值、最佳实践、辅助方法 | 99% 的日常开发场景,首选! |
| L3 | 预制组件 / Patterns | 业务场景化命名 | 极致封装 | 极少 | ✅天花板级 | ❌灵活性低 | 一行代码 = 一套解决方案、内置架构规范 | 通用业务场景、追求极致效率 |
2.6 AWS CDK 三层使用的「黄金原则」
这是 AWS 官方推荐的、所有资深 CDK 开发者都遵循的原则,按这个原则写代码,永远不会出错,效率最高,代码最优雅,优先级从高到低:
原则 1:能用 L3,就优先用 L3
L3 是效率天花板,能帮你省掉大量的重复代码和踩坑,而且是官方最佳实践,稳赚不亏。
原则 2:L3 满足不了,就用 L2
L2 是 CDK 的核心,是平衡「效率」和「灵活度」的最优解,也是日常开发的主力,99% 的场景都能覆盖。
原则 3:L2 满足不了,再用 L1 补充
只有当 L2 没有暴露你需要的底层属性时,才用 L1 做补充配置,不要大面积用 L1 写代码,否则就失去了 CDK 的意义。
原则 4:混合使用完全没问题
CDK 的三层是完全兼容、可以无缝混合使用的,比如:用 L3 创建一套 API 服务,用 L2 配置细节,用 L1 补充一个冷门属性,这是最常见的写法。
2.7 补充 2 个高频问题
Q1:我怎么知道一个资源有没有 L3/L2 封装?
答:查 AWS CDK 的官方文档即可
- L3 组件:在文档中搜索「Patterns」或直接搜业务场景名(比如 LambdaRestApi);
- L2 资源:在文档中搜索对应的服务名(比如 S3 → Bucket,Lambda → Function);
- L1 资源:在文档中搜索「Cfn + 服务名」(比如 CfnBucket,CfnInstance)。
Q2:用 L3 会不会被绑定死?如果后期需要定制化怎么办?
答:不会!L3 创建的所有底层资源,都可以通过属性获取到,然后用 L2 的方法做定制化修改,比如:
1 | // L3创建API Gateway + Lambda |
2.8 总结
- **L1 (CfnXXX)**:CFN 直译,最灵活、最繁琐,底层兜底用;
- **L2 (XXX)**:官方封装,主力首选,99% 场景用它,平衡效率和灵活度;
- **L3 (Patterns)**:场景化预制组件,效率天花板,通用场景优先用;
- 黄金原则:
L3 > L2 > L1,能用高层级就不用低层级; - 核心价值:CDK 的三层封装,本质是「让你用最少的代码,写最合规、最高效的基础设施代码」,不用再像写 CFN 模板一样痛苦。
参考链接:
https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html#about-aws
https://docs.aws.amazon.com/cdk/v2/guide/home.html
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html
https://docs.aws.amazon.com/cdk/
https://github.com/aws/aws-cdk
https://github.com/aws-samples/aws-cdk-examples
https://catalog.us-east-1.prod.workshops.aws/workshops/10141411-0192-4021-afa8-2436f3c66bd8/en-US