这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用cloudformation-include.CfnInclude
构造将资源转换为 L1 结构,将资源从 AWS CloudFormation 模板导入到 AWS Cloud Development Kit (AWS CDK) 应用程序中。
导入后,您可以在应用程序中使用这些资源,方法与最初在 AWS CDK 代码中定义这些资源的方式相同。你也可以在更高级别 AWS CDK 的构造中使用这些 L1 结构。例如,这可以让您将 L2 权限授予方法与其定义的资源一起使用。
该cloudformation-include.CfnInclude
构造本质上是向 AWS CloudFormation 模板中的任何资源添加一个 AWS CDK API 封装器。使用此功能一次将现有 AWS CloudFormation 模板导入到 AWS CDK 一个片段中。通过这样做,您可以使用 AWS CDK 构造来管理现有资源,从而利用更高级别抽象的优势。您还可以使用此功能通过提供 AWS CDK 构造 API 将 AWS CloudFormation 模板出售给 AWS CDK 开发人员。
注意
AWS CDK 还包括 v1 aws-cdk-lib.CfnInclude
,它以前用于相同的通用用途。但是,它缺少 cloudformation-include.CfnInclude
的大部分功能。
导入 AWS CloudFormation 模板
以下是示例 AWS CloudFormation 模板,我们将使用该模板在本主题中提供示例。复制模板并将其保存为 my-template.json
,以供后续操作。完成这些示例后,您可以使用任何现有已部署的 AWS CloudFormation 模板进一步探索。您可以从 AWS CloudFormation
控制台获取模板。
{
"Resources": {
"amzn-s3-demo-bucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": "amzn-s3-demo-bucket",
}
}
}
}
您可以使用 JSON 或 YAML 模板。我们建议使用 JSON(如果可用),因为 YAML 解析器接受的内容可能略有不同。
以下是如何使用将示例模板导入 AWS CDK 应用程序的示例cloudformation-include
。在 CDK 堆栈的上下文中导入模板。
import * as cdk from 'aws-cdk-lib';
import * as cfninc from 'aws-cdk-lib/cloudformation-include';
import { Construct } from 'constructs';
export class MyStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const template = new cfninc.CfnInclude(this, 'Template', {
templateFile: 'my-template.json',
});
}
}
默认情况下,导入资源时会保留模板中资源的原始逻辑 ID。此行为适用于将 AWS CloudFormation 模板导入到 AWS CDK,其中 IDs 必须保留逻辑。 AWS CloudFormation 需要这些信息才能将这些导入的资源识别为 AWS CloudFormation 模板中的相同资源。
如果您正在为模板开发 AWS CDK 构造封装器,以便其他 AWS CDK 开发人员可以使用,请 IDs 改用 AWS CDK 生成新资源。通过这样做,可以在堆栈中多次使用该构造,而不会发生名称冲突。为此,请在导入模板时将 preserveLogicalIds
属性设置为 false
。以下是示例:
const template = new cfninc.CfnInclude(this, 'MyConstruct', {
templateFile: 'my-template.json',
preserveLogicalIds: false
});
要将导入的资源置于您的 AWS CDK 应用程序的控制之下,请将堆栈添加到App
:
import * as cdk from 'aws-cdk-lib';
import { MyStack } from '../lib/my-stack';
const app = new cdk.App();
new MyStack(app, 'MyStack');
要验证堆栈中的 AWS 资源不会发生任何意外更改,您可以执行差异。使用 AWS CDK CLI cdk diff
命令并省略任何 AWS CDK特定的元数据。以下是示例:
cdk diff --no-version-reporting --no-path-metadata --no-asset-metadata
导入 AWS CloudFormation 模板后,该 AWS CDK 应用程序应成为您导入资源的真实来源。要对资源进行更改,请在 AWS CDK 应用程序中对其进行修改,然后使用进行部署 AWS CDK CLI cdk deploy 命令。
访问导入的资源
示例代码template
中的名称代表导入的 AWS CloudFormation 模板。要从中访问资源,请使用对象的 getResource()
方法。要将返回的资源作为特定类型的资源进行访问,请将结果强制转换为所需的类型。这在 Python 中是没有必要的,或者 JavaScript。以下是示例:
const cfnBucket = template.getResource('amzn-s3-demo-bucket') as s3.CfnBucket;
从此示例中,cfnBucket
现在是 aws-s3.CfnBucket
类的实例。这是代表相应 AWS CloudFormation 资源的 L1 结构。您可用将其视为同类型的任何其他资源来对待。例如,您可以使用 bucket.attrArn
属性获取其 ARN 值。
要改为将 L1 CfnBucket
资源包装在 L2 aws-s3.Bucket
实例中,请使用静态方法 fromBucketArn()
、fromBucketAttributes()
或 fromBucketName()
。通常,fromBucketName()
方法最方便。以下是示例:
const bucket = s3.Bucket.fromBucketName(this, 'Bucket', cfnBucket.ref);
其他 L2 构造也有类似的方法,用于从现有资源创建构造。
当您将 L1 构造包装在 L2 构造中时,其不会创建新的资源。在我们的示例中,我们没有创建第二个 S3 存储桶。相反,新的 Bucket
实例封装了现有 CfnBucket
。
在此示例中,bucket
现在是一个 L2 Bucket
构造,其行为与任何其他 L2 构造类似。例如,您可以使用存储桶的便捷grantWrite()
方法向 AWS Lambda 函数授予对该存储桶的写入权限。您不必手动定义必要的 AWS Identity and Access Management (IAM) 策略。以下是示例:
bucket.grantWrite(lambdaFunc);
替换参数
如果您的 AWS CloudFormation 模板包含参数,则可以在导入时使用parameters
属性将其替换为构建时值。在以下示例中,我们将UploadBucket
参数替换为代码中其他地方定义的存储桶的 ARN。 AWS CDK
const template = new cfninc.CfnInclude(this, 'Template', {
templateFile: 'my-template.json',
parameters: {
'UploadBucket': bucket.bucketArn,
},
});
导入其他模板元素
您可以导入任何 AWS CloudFormation 模板元素,而不仅仅是资源。导入的元素将成为 AWS CDK
堆栈的一部分。要导入这些元素,请使用 CfnInclude
对象的以下方法:
-
getCondition()
— AWS CloudFormation 条件。 -
getMapping()
— AWS CloudFormation 映射。 -
getOutput()
— AWS CloudFormation 输出。 -
getParameter()
— AWS CloudFormation 参数。
这些方法中的每一个都返回一个表示特定 AWS CloudFormation 元素类型的类的实例。这些对象是可变的。您对其所做的更改将显示在从 AWS CDK 堆栈生成的模板中。以下是从模板导入参数并修改其默认值的示例:
const param = template.getParameter('MyParameter');
param.default = "AWS CDK"
导入嵌套堆栈
您可以通过在导入嵌套堆栈的主模板时或在稍后某个时刻指定嵌套堆栈来导入嵌套模板。嵌套模板必须存储在本地文件中,但在主模板中作为 NestedStack
资源引用。此外, AWS CDK 代码中使用的资源名称必须与主模板中用于嵌套堆栈的名称相匹配。
在主模板中给定此资源定义,以下代码显示了如何以两种方法导入引用的嵌套堆栈。
"NestedStack": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"TemplateURL": "https://my-s3-template-source.s3.amazonaws.com/nested-stack.json"
}
// include nested stack when importing main stack
const mainTemplate = new cfninc.CfnInclude(this, 'MainStack', {
templateFile: 'main-template.json',
loadNestedStacks: {
'NestedStack': {
templateFile: 'nested-template.json',
},
},
});
// or add it some time after importing the main stack
const nestedTemplate = mainTemplate.loadNestedStack('NestedTemplate', {
templateFile: 'nested-template.json',
});
您可以使用任一方法来导入多个嵌套堆栈。导入主模板时,您需要提供每个嵌套堆栈的资源名称与其模板文件之间的映射。此映射可以包含任意数量的条目。要在初始导入后执行此操作,请为每个嵌套堆栈调用一次 loadNestedStack()
。
导入嵌套堆栈后,您可以使用主模板的 getNestedStack()
方法对其进行访问。
const nestedStack = mainTemplate.getNestedStack('NestedStack').stack;
该 getNestedStack()
方法会返回一个 IncludedNestedStack
实例。在此实例中,您可以通过stack
属性访问 AWS CDK NestedStack
实例,如示例所示。您也可以通过访问原始 AWS CloudFormation 模板对象includedTemplate
,从中加载资源和其他 AWS CloudFormation 元素。