第 1 层构造 - AWS 规范指引

第 1 层构造

L1 构造是 AWS CDK 的构建块,可以很容易地通过前缀 Cfn 与其他构造区分开来。例如,AWS CDK 中的 Amazon DynamoDB 软件包包含 Table 构造,它是 L2 构造。相应的 L1 构造称为 CfnTable,它直接表示 CloudFormation DynamoDB Table。虽然 AWS CDK 应用程序通常从不直接使用 L1 构造,但如果不访问第一层,就无法使用 AWS CDK。但是,在大多数情况下,开发者习惯使用的 L2 和 L3 构造在很大程度上依赖于 L1 构造。因此,您可以将 L1 构造视为 CloudFormation 和 AWS CDK 之间的桥梁。

AWS CDK 的唯一目的是使用标准编码语言生成 CloudFormation 模板。运行 cdk synth CLI 命令并生成 CloudFormation 模板后,AWS CDK 的作业就完成了。cdk deploy 命令只是为了方便而存在的,但运行该命令时所执行的操作完全是在 CloudFormation 内完成的。将 AWS CDK 代码转换为 CloudFormation 可理解的格式的关键在于 L1 构造。

L1 构造的 AWS CDK–CloudFormation 生命周期

创建和使用 L1 构造的过程包括以下步骤:

  1. AWS CDK 构建过程将 CloudFormation 规范转换为 L1 构造形式的编程代码。

  2. 开发者编写的代码可以直接或间接引用 L1 构造作为 AWS CDK 应用程序的一部分。

  3. 开发者运行 cdk synth 命令将编程代码转换回 CloudFormation 规范(模板)规定的格式。

  4. 开发者运行 cdk deploy 命令将这些模板内的 CloudFormation 堆栈部署到 AWS 账户环境中。

我们来做个小练习。前往 GitHub 上的 AWS CDK 开源存储库,随机选择一种 AWS 服务,然后转到该服务的 AWS CDK 软件包(位于文件夹 packagesaws-cdk-libaws-<servicename>lib 中)。在本示例中,让我们选择 Amazon S3,但这适用于任何服务。如果您查看该软件包的主 index.ts 文件,您会看到一行内容为:

export * from './s3.generated';

但是,您不会在相应目录中的任何地方看到 s3.generated 文件。这是因为 L1 构造是在 AWS CDK 构建过程中根据 CloudFormation 资源规范自动生成的。因此,只有在您运行软件包的 AWS CDK 构建命令后,您才会在软件包中看到 s3.generated

AWS CloudFormation 资源规范

AWS CloudFormation 资源规范定义了 AWS 的基础设施即代码(IAC),并确定了 CloudFormation 模板内的代码如何转换为 AWS 账户中的资源。此规范在每个区域级别以 JSON 格式定义 AWS 资源。每个资源都有一个唯一的资源类型名称,该名称遵循 provider::service::resource 格式。例如,Amazon S3 存储桶的资源类型名称将为 AWS::S3::Bucket,Amazon S3 接入点的资源类型名称将为 AWS::S3::AccessPoint。这些资源类型可以使用 AWS CloudFormation 资源规范中定义的语法在 CloudFormation 模板中呈现。AWS CDK 构建过程运行时,每种资源类型也将变为 L1 构造。

因此,每个 L1 构造都是其相应的 CloudFormation 资源的编程镜像。当您实例化 L1 构造时,您要在 CloudFormation 模板中应用的每个属性都可用;在实例化相应的 L1 构造时,还需要将每个必需的 CloudFormation 属性作为参数。下表将 CloudFormation 模板中表示的 S3 存储桶与定义为 AWS CDK L1 构造的相同 S3 存储桶进行了比较。

CloudFormation 模板

L1 构造

"amzns3demobucket": { "Type": "AWS::S3::Bucket", "Properties": { "BucketName": "amzn-s3-demo-bucket", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { "ServerSideEncryptionByDefault": { "SSEAlgorithm": "AES256" } } ] }, "MetricsConfigurations": [ { "Id": "myConfig" } ], "OwnershipControls": { "Rules": [ { "ObjectOwnership": "BucketOwnerPreferred" } ] }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, "IgnorePublicAcls": true, "RestrictPublicBuckets": true }, "VersioningConfiguration": { "Status": "Enabled" } } }
new CfnBucket(this, "amzns3demobucket", { bucketName: "amzn-s3-demo-bucket", bucketEncryption: { serverSideEncryptionConfiguration: [ { serverSideEncryptionByDefault: { sseAlgorithm: "AES256" } } ] }, metricsConfigurations: [ { id: "myConfig" } ], ownershipControls: { rules: [ { objectOwnership: "BucketOwnerPreferred" } ] }, publicAccessBlockConfiguration: { blockPublicAcls: true, blockPublicPolicy: true, ignorePublicAcls: true, restrictPublicBuckets: true }, versioningConfiguration: { status: "Enabled" } });

如您所见,L1 构造是 CloudFormation 资源代码中的精确体现。没有捷径或简化方法,因此必须编写的样板文本数量大致相同。但是,使用 AWS CDK 的主要优势之一应该是它有助于消除许多样板 CloudFormation 语法。那么,这是怎么发生的呢? 这就是 L2 构造发挥作用的地方。