在 CDK 中包含 CloudFormation 模板
AWS CDK v1在2023-06-01上达到了支持结束. 此软件包不再更新,用户应该迁移到 AWS CDK v2.
关于如何移徙的更多信息,请参见: 移动到 AWS CDK v2 指南。 。 。 .
本单元包含一组班级,其目标在于促进就业
在 CDK 中带有已存在的 CloudFormation 模板.
可以认为是扩展了
CfnInclude 类。 。 。 .
基本用途
假设我们有一个文件 与已有的模板.
它可能是JSON格式的, 在一个文件中 my-template.json数字 :
{
"Resources": {
"Bucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": "some-bucket-name"
}
}
}
}
或者可以用YAML格式,在文件中 my-template.yaml数字 :
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: some-bucket-name
它可以包含在CDK应用程序中,其代码如下:
const cfnTemplate = new cfn_inc.CfnInclude(this, 'Template', {
templateFile: 'my-template.json',
});
或者,如果您的模板使用YAML:
const cfnTemplate = new cfn_inc.CfnInclude(this, 'Template', {
templateFile: 'my-template.yaml',
});
说明:不同的YAML解析器有时对何为有效的YAML并不认同. 如果您在包含模板时获得YAML的例外, 尝试将其转换为 JSON, 并包含该文件 . 如果您正在下载您的模板 从 Cloud Formation AWS Console, 您可以点击“ 在设计器中查看” , 轻松地以 JSON 格式获取 选项卡上的按钮 - 一次在 Designer 中,用“ 选择 JSON ” 模板语言 底板上的无线电按钮.
这将增加来自 my-template.json 编号 : my-template.yaml 输入 CDK 应用程序,
从模板文件中保留其原始逻辑ID.
请注意,包括这一进程在内的工作将: 没有 执行任何 云阵变换 - 说吧 包括《京都议定书》 无服务器转换。 。 。 .
从包含的模板中获取的任何资源都可以通过从模板中引用其逻辑ID来获取. 如果您知道该资源对应的 CDK 对象的类别, 您可以将返回对象投放到正确的类型:
declare const cfnTemplate: cfn_inc.CfnInclude;
const cfnBucket = cfnTemplate.getResource('Bucket') as s3.CfnBucket;
// cfnBucket is of type s3.CfnBucket
注意最新版本 CloudFormation 方案中没有的任何资源
在发布您所依赖的这个模块的版本时,
包括 自定义资源, (中文(简体) ),
将返回为类例 CfnResource, (中文(简体) ),
因此不能投放到不同的资源类型.
对该资源的任何修改将反映在产生的CDK模板中; 例如,可以更改桶名:
declare const cfnTemplate: cfn_inc.CfnInclude;
const cfnBucket = cfnTemplate.getResource('Bucket') as s3.CfnBucket;
cfnBucket.bucketName = 'my-bucket-name';
您也可以在定义其他构造时引用资源 ,
包括高级别
(其名称不从 Cfn, (中文(简体) ),
例如:
declare const cfnTemplate: cfn_inc.CfnInclude;
const cfnBucket = cfnTemplate.getResource('Bucket') as s3.CfnBucket;
const role = new iam.Role(this, 'Role', {
assumedBy: new iam.AnyPrincipal(),
});
role.addToPolicy(new iam.PolicyStatement({
actions: ['s3:*'],
resources: [cfnBucket.attrArn],
}));
将 L1 资源转换为 L2
资源 getResource 方法返回是 CDK 所谓的
第一层资源
(比如说) CfnBucket) (中文(简体) ).
然而,在建筑图书馆的许多地方,
cDK 需要所谓的 第2层资源,例如 IBucket。 。 。 .
从L1到L2资源有两种方式.
使用fromCfn*() 方法
这是将L1资源转换为L2的首选方法.
L2 资源类的静态方法
谁的名字从 fromCfn - 说吧
例如,对于 KMS 密钥 Kms.fromCfnKey() 方法 -
将L1作为论据:
declare const cfnTemplate: cfn_inc.CfnInclude;
const cfnKey = cfnTemplate.getResource('Key') as kms.CfnKey;
const key = kms.Key.fromCfnKey(cfnKey);
返回一个实例 kms.IKey 类型,可以在 CDK 中通过 IKey 预期.
还有.. IKey 实例会变异 -
意思是把任何变异方法都叫上去,
喜欢 addToResourcePolicy(), (中文(简体) ),
将反映在所产生的模板中.
注意在某些情况下 fromCfn*() 方法可能无法从基本的L1中创建 L2 .
当基础L1大量使用CloudFormation函数时,这种情况可能发生.
例如,如果尝试创建 L2 IKey
从此 CloudFormation 模板所代表的 L1 中:
{
"Resources": {
"Key": {
"Type": "AWS::KMS::Key",
"Properties": {
"KeyPolicy": {
"Statement": [
{
"Fn::If": [
"Condition",
{
"Action": "kms:if-action",
"Resource": "*",
"Principal": "*",
"Effect": "Allow"
},
{
"Action": "kms:else-action",
"Resource": "*",
"Principal": "*",
"Effect": "Allow"
}
]
}
],
"Version": "2012-10-17"
}
}
}
}
}
这个 Key.fromCfnKey() 方法不知道如何将它转化为CDK L2概念,
并放弃一个例外.
在这种情况下,需要使用第二种方法将一L1转换为一L2.
使用 from*Name/Arn/Attributes() 方法
如果您需要的资源没有 fromCfn*() 方法,
或者,如果它确实存在,但它为您特定的L1投出一个例外,
您需要使用第二种方法将 L1 资源转换为 L2 .
每一个L2级都有静态工厂方法 名字像 from*Name(), (中文(简体) ),
from*Arn(),和(或) from*Attributes()。 。 。 .
您可以通过将 L1 的正确属性传递给这些方法来获取 L1 资源 :
declare const cfnTemplate: cfn_inc.CfnInclude;
// using from*Name()
const cfnBucket = cfnTemplate.getResource('Bucket') as s3.CfnBucket;
const bucket = s3.Bucket.fromBucketName(this, 'L2Bucket', cfnBucket.ref);
// using from*Arn()
const cfnKey = cfnTemplate.getResource('Key') as kms.CfnKey;
const key = kms.Key.fromKeyArn(this, 'L2Key', cfnKey.attrArn);
// using from*Attributes()
declare const privateCfnSubnet1: ec2.CfnSubnet;
declare const privateCfnSubnet2: ec2.CfnSubnet;
const cfnVpc = cfnTemplate.getResource('Vpc') as ec2.CfnVPC;
const vpc = ec2.Vpc.fromVpcAttributes(this, 'L2Vpc', {
vpcId: cfnVpc.ref,
availabilityZones: core.Fn.getAzs(),
privateSubnetIds: [privateCfnSubnet1.ref, privateCfnSubnet2.ref],
});
只要他们需要参考,
绝不改变一切,一切都应成功;
然而,注意到这些方法所节省的资源,
和那些返回的不一样 fromCfn*() 方法,
不可改变的 也就是说 任何变异方法都无效.
你必须改变L1 才能改变它们.
非资源模板要素
除资源外, ,也可以获取和变异所有其他模板元素:
-
参数数字 :
declare const cfnTemplate: cfn_inc.CfnInclude; const param: core.CfnParameter = cfnTemplate.getParameter('MyParameter'); // mutating the parameter param.default = 'MyDefault'; -
条件数字 :
declare const cfnTemplate: cfn_inc.CfnInclude; const condition: core.CfnCondition = cfnTemplate.getCondition('MyCondition'); // mutating the condition condition.expression = core.Fn.conditionEquals(1, 2); -
绘图数字 :
declare const cfnTemplate: cfn_inc.CfnInclude; const mapping: core.CfnMapping = cfnTemplate.getMapping('MyMapping'); // mutating the mapping mapping.setValue('my-region', 'AMI', 'ami-04681a1dbd79675a5'); -
服务目录模板规则数字 :
declare const cfnTemplate: cfn_inc.CfnInclude; const rule: core.CfnRule = cfnTemplate.getRule('MyRule'); // mutating the rule declare const myParameter: core.CfnParameter; rule.addAssertion(core.Fn.conditionContains(['m1.small'], myParameter.valueAsString), 'MyParameter has to be m1.small'); -
产出数字 :
declare const cfnTemplate: cfn_inc.CfnInclude; const output: core.CfnOutput = cfnTemplate.getOutput('MyOutput'); // mutating the output declare const cfnBucket: s3.CfnBucket; output.value = cfnBucket.attrArn; -
蓝绿色部署用钩数字 :
declare const cfnTemplate: cfn_inc.CfnInclude; const hook: core.CfnHook = cfnTemplate.getHook('MyOutput'); // mutating the hook declare const myRole: iam.Role; const codeDeployHook = hook as core.CfnCodeDeployBlueGreenHook; codeDeployHook.serviceRole = myRole.roleArn;
参数替换
如果您的模板使用了 CloudFormation 参数,
您可能想要删除它们, 以有利于构建时间值.
你可以用这个 parameters 属性 :
new cfn_inc.CfnInclude(this, 'includeTemplate', {
templateFile: 'path/to/my/template',
parameters: {
'MyParam': 'my-value',
},
});
这将取代所有提及 MyParam 带字符串 'my-value', (中文(简体) ),
财务报告和审定财务报表 MyParam 将被从生成模板的“参数”部分去除.
嵌入式堆栈
此模块还支持使用模板 嵌入式堆栈。 。 。 .
例如,如果您的父模板如下:
{
"Resources": {
"ChildStack": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"TemplateURL": "https://my-s3-template-source.s3.amazonaws.com/child-stack.json"
}
}
}
}
其中,儿童模板指向 https://my-s3-template-source.s3.amazonaws.com/child-stack.json 为:
{
"Resources": {
"MyBucket": {
"Type": "AWS::S3::Bucket"
}
}
}
你可以包括两个母堆, 和CDK应用程序中的嵌入堆栈如下:
const parentTemplate = new cfn_inc.CfnInclude(this, 'ParentStack', {
templateFile: 'path/to/my-parent-template.json',
loadNestedStacks: {
'ChildStack': {
templateFile: 'path/to/my-nested-template.json',
},
},
});
这里, path/to/my-nested-template.json
代表磁盘上从嵌入堆栈的原始模板 URL 下载模板文件的路径
(单位:千美元)https://my-s3-template-source.s3.amazonaws.com/child-stack.json) (中文(简体) ).
在CDK应用程序中,
此文件将变为 资产, (中文(简体) ),
编辑 TemplateURL 嵌入式堆栈资源属性
将修改以指出该资产.
包含的嵌入式堆栈可访问 getNestedStack 方法 :
declare const parentTemplate: cfn_inc.CfnInclude;
const includedChildStack = parentTemplate.getNestedStack('ChildStack');
const childStack: core.NestedStack = includedChildStack.stack;
const childTemplate: cfn_inc.CfnInclude = includedChildStack.includedTemplate;
现在可以参考来自 ChildStack, (中文(简体) ),
并与其他包含的模板一样对其进行修改:
declare const childTemplate: cfn_inc.CfnInclude;
const cfnBucket = childTemplate.getResource('MyBucket') as s3.CfnBucket;
cfnBucket.bucketName = 'my-new-bucket-name';
const role = new iam.Role(this, 'MyRole', {
assumedBy: new iam.AccountRootPrincipal(),
});
role.addToPolicy(new iam.PolicyStatement({
actions: [
's3:GetObject*',
's3:GetBucket*',
's3:List*',
],
resources: [cfnBucket.attrArn],
}));
还可以包括: CfnInclude 对象被创建,
而不是在建筑上这样做:
declare const parentTemplate: cfn_inc.CfnInclude;
const includedChildStack = parentTemplate.loadNestedStack('ChildTemplate', {
templateFile: 'path/to/my-nested-template.json',
});
将云格式模板作为构造
在许多情况下,现有的 Cloud Formation 模板不是整个应用程序,
但更像是专门的片段, 执行特定的模式或最佳做法.
如果你有这样的模板,
您可以使用 CfnInclude 类以 CDK 建构方式进行 :
import { Construct } from 'constructs';
import * as cfn_inc from '@aws-cdk/cloudformation-include';
import * as path from 'path';
export class MyConstruct extends Construct {
constructor(scope: Construct, id: string) {
super(scope, id);
// include a template inside the Construct
new cfn_inc.CfnInclude(this, 'MyConstruct', {
templateFile: path.join(__dirname, 'my-template.json'),
preserveLogicalIds: false, // <--- !!!
});
}
}
注意到 preserveLogicalIds 参数 -
它确保包含的所有模板元素的逻辑ID使用CDK的算法重新命名,
保证它们在您的申请中是独一无二的.
没有这个参数通过,
即时 MyConstruct 在同一堆中两次将产生重复的逻辑ID.