这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用 AWS CDK 库
导入并使用 AWS 云开发工具包 (AWS CDK) 库,以使用支持的编程语言来定义您的 AWS 云基础设施。
导入 AWS CDK 库
通常通过 AWS CDK 库 的 TypeScript 包名称 aws-cdk-lib 来引用该库。实际的包名称因语言而异。以下是如何安装和导入 CDK 库的示例:
- TypeScript
-
|
安装
|
npm install aws-cdk-lib
|
|
导入:
|
import * as cdk from 'aws-cdk-lib';
|
- JavaScript
-
|
安装
|
npm install aws-cdk-lib
|
|
导入:
|
const cdk = require('aws-cdk-lib');
|
- Python
-
|
安装
|
python -m pip install aws-cdk-lib
|
|
导入:
|
import aws_cdk as cdk
|
- Java
-
|
在 pom.xml 中,添加
|
Group software.amazon.awscdk; artifact aws-cdk-lib
|
|
导入:
|
import software.amazon.awscdk.App;
|
- C#
-
|
安装
|
dotnet add package Amazon.CDK.Lib
|
|
导入:
|
using Amazon.CDK;
|
- Go
-
|
安装
|
go get github.com/aws/aws-cdk-go/awscdk/v2
|
|
导入:
|
import (
"github.com/aws/aws-cdk-go/awscdk/v2"
)
|
construct 基类和支持代码位于 constructs 库中。实验性构造(其中 API 仍在完善中)作为单独的模块进行分发。
使用 AWS CDK API 参考
采用 AWS CDK 进行开发时,请使用 AWS CDK API 参考。
每个模块的参考资料分为以下几个部分。
-
概述:使用 AWS CDK 中的服务需要了解的介绍性材料,包括概念和示例。
-
构造:表示一个或多个具体 AWS 资源的库类。这些是“精选”(L2)资源或模式(L3 资源),可提供具有合理默认值的高级别接口。
-
类:非构造类,可提供模块中构造所使用的功能。
-
结构:数据结构(属性捆绑包),可定义复合值结构,例如属性(构造的 props 参数)和选项。
-
接口:所有名称以“I”为开头的接口,可定义相应构造或其他类的绝对最低功能。CDK 使用构造接口来表示在您的 AWS CDK 应用程序之外定义并由 Bucket.fromBucketArn() 等方法引用的 AWS 资源。
-
枚举:用于指定某些构造参数的命名值的集合。使用枚举值可允许 CDK 在合成过程中检查这些值的有效性。
-
CloudFormation 资源:名称以“Cfn”开头的这些 L1 构造,正好代表了 CloudFormation 规范中定义的资源。这些资源随每个 CDK 版本根据该规范自动生成。每个 L2 或 L3 构造都封装了一个或多个 CloudFormation 资源。
-
CloudFormation 属性类型:定义每个 CloudFormation 资源属性的命名值的集合。
接口与构造类的比较
AWS CDK 以特定的方式使用接口,即使您熟悉作为编程概念的接口,这种方式也可能并不明显。
AWS CDK 支持通过 Bucket.fromBucketArn() 等方法来使用 CDK 应用程序之外定义的资源。无法对外部资源进行修改,并且可能不具有使用 Bucket 类等工具在您的 CDK 应用程序中定义的资源提供的所有功能。因此,接口代表了 CDK 中针对给定 AWS 资源类型(包括外部资源)可用的最低功能。
所以在 CDK 应用程序中实例化资源时,应始终使用具体的类,例如 Bucket。在您自己的构造之一中指定要接受的参数类型时,如果您已准备好处理外部资源(即无需对其进行更改),请使用 IBucket 等接口类型。如果需要 CDK 定义的构造,请指定可以使用的最通用的类型。
有些接口是与特定类(而不是构造)相关的属性或选项捆绑包的最低版本。当进行子类化以接受要传递给父类的参数时,此类接口会很有用。如果您需要一个或多个其他属性,则需要从该接口或更具体的类型来实现或派生。
AWS CDK 支持的某些编程语言不具备接口功能。在这些语言中,接口只是普通的类。您可以通过其名称来进行识别,这些名称遵循首字母为“I”后跟其他构造名称的模式(例如 IBucket)。适用于相同的规则。
管理依赖项
使用包管理工具来管理 AWS CDK 应用程序或库的依赖项。这些工具通常与编程语言一起使用。
通常,AWS CDK 支持该语言的标准或官方包管理工具(如有)。否则,AWS CDK 将支持该语言中最常用或最广泛支持的管理工具。您也可以使用其他工具,特别是如果与支持的工具配合使用。但是,官方对其他工具的支持有限。
AWS CDK 支持以下包管理器:
| 语言 |
支持的包管理工具 |
|
TypeScript/JavaScript
|
NPM(节点包管理器)或 Yarn
|
|
Python
|
PIP(Python 的包安装程序)
|
|
Java
|
Maven
|
|
C#
|
NuGet
|
|
Go(转到)
|
Go 模块
|
使用 AWS CDK CLI cdk init 命令创建新项目时,会自动指定 CDK 核心库和稳定构造的依赖项。
有关管理受支持编程语言依赖项的更多信息,请参阅以下内容:
将 TypeScript 中的 AWS CDK 与其他语言进行比较
TypeScript 是支持开发 AWS CDK 应用程序所支持的第一种语言。因此,大量示例 CDK 代码都使用 TypeScript 进行编写。如果您正在使用另一种语言进行开发,那么请将 AWS CDK 代码在 TypeScript 中的实现方式与您选择语言中的实现方式进行比较,这可能会很有用。这有助于您在整个文档中使用示例。
导入模块
- TypeScript/JavaScript
-
TypeScript 支持导入整个命名空间,也支持从某个命名空间中导入单个对象。每个命名空间都包含用于给定 AWS 服务的构造和其他类。
// Import main CDK library as cdk
import * as cdk from 'aws-cdk-lib'; // ES6 import preferred in TS
const cdk = require('aws-cdk-lib'); // Node.js require() preferred in JS
// Import specific core CDK classes
import { Stack, App } from 'aws-cdk-lib';
const { Stack, App } = require('aws-cdk-lib');
// Import AWS S3 namespace as s3 into current namespace
import { aws_s3 as s3 } from 'aws-cdk-lib'; // TypeScript
const s3 = require('aws-cdk-lib/aws-s3'); // JavaScript
// Having imported cdk already as above, this is also valid
const s3 = cdk.aws_s3;
// Now use s3 to access the S3 types
const bucket = s3.Bucket(...);
// Selective import of s3.Bucket
import { Bucket } from 'aws-cdk-lib/aws-s3'; // TypeScript
const { Bucket } = require('aws-cdk-lib/aws-s3'); // JavaScript
// Now use Bucket to instantiate an S3 bucket
const bucket = Bucket(...);
- Python
-
与 TypeScript 一样,Python 也支持具有命名空间的模块导入和选择性导入。Python 中的命名空间类似于 aws_cdk. xxx,其中 xxx 表示 AWS 服务名称,例如 s3 代表 Amazon S3。(这些示例中使用了 Amazon S3。)
# Import main CDK library as cdk
import aws_cdk as cdk
# Selective import of specific core classes
from aws_cdk import Stack, App
# Import entire module as s3 into current namespace
import aws_cdk.aws_s3 as s3
# s3 can now be used to access classes it contains
bucket = s3.Bucket(...)
# Selective import of s3.Bucket into current namespace
from aws_cdk.s3 import Bucket
# Bucket can now be used to instantiate a bucket
bucket = Bucket(...)
- Java
-
Java 的导入方式与 TypeScript 有所不同。每个 import 语句要么从给定包中导入单个类名,要么导入该包中定义的所有类(使用 \*)。可以使用类本身的类名(如果已导入该类),也可以使用包含其包的限定类名来访问类。
库的命名类似于 AWS 构造库的 software.amazon.awscdk.services.xxx(其中 software.amazon.awscdk 为主库)。AWS CDK 软件包的 Maven 组 ID 为 software.amazon.awscdk。
// Make certain core classes available
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.App;
// Make all Amazon S3 construct library classes available
import software.amazon.awscdk.services.s3.*;
// Make only Bucket and EventType classes available
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.s3.EventType;
// An imported class may now be accessed using the simple class name (assuming that name
// does not conflict with another class)
Bucket bucket = Bucket.Builder.create(...).build();
// We can always use the qualified name of a class (including its package) even without an
// import directive
software.amazon.awscdk.services.s3.Bucket bucket =
software.amazon.awscdk.services.s3.Bucket.Builder.create(...)
.build();
// Java 10 or later can use var keyword to avoid typing the type twice
var bucket =
software.amazon.awscdk.services.s3.Bucket.Builder.create(...)
.build();
- C#
-
在 C# 中,您可以使用 using 指令导入类型。有两种方式可供选择。一种是使用纯名称来访问指定命名空间中的所有类型。另一种则是可以使用别名来引用命名空间本身。
软件包的命名类似于 AWS 构造库软件包的 Amazon.CDK.AWS.xxx。(其中 Amazon.CDK 为核心模块。)
// Make CDK base classes available under cdk
using cdk = Amazon.CDK;
// Make all Amazon S3 construct library classes available
using Amazon.CDK.AWS.S3;
// Now we can access any S3 type using its name
var bucket = new Bucket(...);
// Import the S3 namespace under an alias
using s3 = Amazon.CDK.AWS.S3;
// Now we can access an S3 type through the namespace alias
var bucket = new s3.Bucket(...);
// We can always use the qualified name of a type (including its namespace) even without a
// using directive
var bucket = new Amazon.CDK.AWS.S3.Bucket(...);
- Go
-
每个 AWS 构造库模块都作为 Go 包提供。
import (
"github.com/aws/aws-cdk-go/awscdk/v2" // CDK core package
"github.com/aws/aws-cdk-go/awscdk/v2/awss3" // AWS S3 construct library module
)
// now instantiate a bucket
bucket := awss3.NewBucket(...)
// use aliases for brevity/clarity
import (
cdk "github.com/aws/aws-cdk-go/awscdk/v2" // CDK core package
s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3" // AWS S3 construct library module
)
bucket := s3.NewBucket(...)
实例化构造
AWS CDK 构造类在所有支持的语言中都具有相同的名称。大多数语言都使用 new 关键字来实例化类(Python 和 Go 则不使用)。此外,在大多数语言中,关键字this 是指当前实例。(按照惯例,Python 使用 self。) 您应该将对当前实例的引用作为 scope 参数传递给您创建的每个构造。
AWS CDK 构造的第三个参数是 props,这是一个包含构建构造所需属性的对象。此参数可能是可选的,但是当需要时,支持的语言会以惯用方式进行处理。属性的名称也符合该语言的标准命名模式。
- TypeScript/JavaScript
-
// Instantiate default Bucket
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket');
// Instantiate Bucket with bucketName and versioned properties
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
bucketName: 'amzn-s3-demo-bucket',
versioned: true,
});
// Instantiate Bucket with websiteRedirect, which has its own sub-properties
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
websiteRedirect: {host: 'aws.amazon.com'}});
- Python
-
Python 在实例化类时不使用 new 关键字。使用关键字参数来表示属性参数,这些关键字参数使用 snake_case 来命名。
如果 props 值本身就是属性捆绑包,则由以该属性命名的类表示,该类接受子属性的关键字参数。
在 Python 中,当前实例作为第一个参数传递给方法,按照惯例命名为 self。
# Instantiate default Bucket
bucket = s3.Bucket(self, "amzn-s3-demo-bucket")
# Instantiate Bucket with bucket_name and versioned properties
bucket = s3.Bucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket", versioned=true)
# Instantiate Bucket with website_redirect, which has its own sub-properties
bucket = s3.Bucket(self, "amzn-s3-demo-bucket", website_redirect=s3.WebsiteRedirect(
host_name="aws.amazon.com"))
- Java
-
在 Java 中,props 参数由一个名为 XxxxProps 的类表示(例如,BucketProps 表示 Bucket 构造的 props)。您可以使用生成器模式来构建 props 参数。
每个 XxxxProps 类都有一个生成器。每个构造都还具有一个便捷生成器,可以一步构建 props 和构造,如以下示例所示。
Props 与 TypeScript 中相同,均使用 camelCase。
// Instantiate default Bucket
Bucket bucket = Bucket(self, "amzn-s3-demo-bucket");
// Instantiate Bucket with bucketName and versioned properties
Bucket bucket = Bucket.Builder.create(self, "amzn-s3-demo-bucket")
.bucketName("amzn-s3-demo-bucket").versioned(true)
.build();
# Instantiate Bucket with websiteRedirect, which has its own sub-properties
Bucket bucket = Bucket.Builder.create(self, "amzn-s3-demo-bucket")
.websiteRedirect(new websiteRedirect.Builder()
.hostName("aws.amazon.com").build())
.build();
- C#
-
在 C# 中,使用对象初始化程序将 props 指定给名为 XxxxProps 的类(例如,BucketProps 表示 Bucket 构造的 props)。
Props 命名与 TypeScript 类似,唯一的不同是使用 PascalCase。
在实例化构造时使用 var 关键字很方便,因此无需键入类名两次。但是,您的本地代码风格指南可能会有所不同。
// Instantiate default Bucket
var bucket = Bucket(self, "amzn-s3-demo-bucket");
// Instantiate Bucket with BucketName and Versioned properties
var bucket = Bucket(self, "amzn-s3-demo-bucket", new BucketProps {
BucketName = "amzn-s3-demo-bucket",
Versioned = true});
// Instantiate Bucket with WebsiteRedirect, which has its own sub-properties
var bucket = Bucket(self, "amzn-s3-demo-bucket", new BucketProps {
WebsiteRedirect = new WebsiteRedirect {
HostName = "aws.amazon.com"
}});
- Go
-
要在 Go 中创建构造,请调用函数 NewXxxxxx,其中 Xxxxxxx 为构造的名称。构造的属性被定义为结构。
在 Go 中,所有构造参数都是指针,包括数字、布尔值和字符串等值。使用 jsii.String 等便捷函数来创建这些指针。
// Instantiate default Bucket
bucket := awss3.NewBucket(stack, jsii.String("amzn-s3-demo-bucket"), nil)
// Instantiate Bucket with BucketName and Versioned properties
bucket1 := awss3.NewBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.BucketProps{
BucketName: jsii.String("amzn-s3-demo-bucket"),
Versioned: jsii.Bool(true),
})
// Instantiate Bucket with WebsiteRedirect, which has its own sub-properties
bucket2 := awss3.NewBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.BucketProps{
WebsiteRedirect: &awss3.RedirectTarget{
HostName: jsii.String("aws.amazon.com"),
}})
访问成员
通常会引用构造和其他 AWS CDK 类的特性或属性,并将这些值用作构建其他构造的输入等。前面所述方法的命名差异也适用于此处。此外,无法在 Java 中直接访问成员。相反,会提供一个 getter 方法。
- TypeScript/JavaScript
-
名称为 camelCase。
bucket.bucketArn
- Python
-
名称为 snake_case。
bucket.bucket_arn
- Java
-
为每个属性提供了一个 getter 方法;这些名称为 camelCase。
bucket.getBucketArn()
- C#
-
名称为 PascalCase。
bucket.BucketArn
- Go
-
名称为 PascalCase。
bucket.BucketArn
枚举常量
枚举常量的作用域仅限于某个类,并且在所有语言中都具有带下划线的大写名称(有时称为 SCREAMING_SNAKE_CASE)。由于类名在除 Go 之外的所有支持的语言中也使用相同的大小写,所以这些语言中的限定枚举名称也相同。
s3.BucketEncryption.KMS_MANAGED
在 Go 中,枚举常量是指模块命名空间的属性,编写方式如下。
awss3.BucketEncryption_KMS_MANAGED
对象接口
AWS CDK 使用 TypeScript 对象接口来表示某个类实现了一组预期的方法和属性。您可以识别对象接口,因为其名称以 I 开头。具体类使用 implements 关键字来指示其实现的接口。
- TypeScript/JavaScript
-
JavaScript 不具备接口功能。您可以忽略 implements 关键字及其后的类名。
import { IAspect, IConstruct } from 'aws-cdk-lib';
class MyAspect implements IAspect {
public visit(node: IConstruct) {
console.log('Visited', node.node.path);
}
}
- Python
-
Python 不具备接口功能。但是,对于 AWS CDK 来说,您可以通过 @jsii.implements(interface) 来装饰您的类,以此指示接口实现。
from aws_cdk import IAspect, IConstruct
import jsii
@jsii.implements(IAspect)
class MyAspect():
def visit(self, node: IConstruct) -> None:
print("Visited", node.node.path)
- Java
-
import software.amazon.awscdk.IAspect;
import software.amazon.awscdk.IConstruct;
public class MyAspect implements IAspect {
public void visit(IConstruct node) {
System.out.format("Visited %s", node.getNode().getPath());
}
}
- C#
-
using Amazon.CDK;
public class MyAspect : IAspect
{
public void Visit(IConstruct node)
{
System.Console.WriteLine($"Visited ${node.Node.Path}");
}
}
- Go
-
Go 结构无需明确声明其实现的接口。Go 编译器根据结构上可用的方法和属性来确定实现。例如,在以下代码中,MyAspect 实现 IAspect 接口,因为其提供了一种采用构造的 Visit 方法。
type MyAspect struct {
}
func (a MyAspect) Visit(node constructs.IConstruct) {
fmt.Println("Visited", *node.Node().Path())
}