本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
创建或扩展构造
什么是构造
构造是 AWS CDK 应用程序的基本构建块。结构可以表示单个 AWS 资源,例如亚马逊简单存储服务 (Amazon S3) Service 存储桶,也可以是由多个相关资源组成的更高级别的抽象。 AWS 构造的组件可以包括具有相关计算能力的工作队列,或者具有监控资源和控制面板的计划作业。 AWS CDK
包括一个名为 “构造库” 的 AWS 构造集合。该库包含每个 AWS 服务的构造。您可以使用 C
onstruc
构造有哪些不同的类型
有三种不同类型的构造: AWS CDK
L1 构造
— 第 1 层或 L1 结构正是由 CloudFormation —不多也不少定义的资源。您必须自己提供配置所需的资源。这些 L1 结构非常基本,必须手动配置。 L1 构造有一个
Cfn
前缀,直接对应于规范。 CloudFormation 只要 CloudFormation 支持 AWS 服务 这些服务 AWS CDK ,就会立即支持新服务。
CfnBucket
是 L1 构造的一个很好的例子。该类表示一个 S3 存储桶,您必须在其中明确配置所有属性。我们建议您仅在找不到 L1 构造的 L2 或 L3 构造时才使用 L1 构造。
L2 构造 - 第 2 层或 L2 构造具有通用的样板代码和粘合逻辑。这些结构带有方便的默认值,减少了您需要了解的有关它们的知识量。L2 构造使用基于意图的 API 来构造您的资源,并且通常封装其相应的 L1 模块。L2 构造的一个很好的例子是 存储桶 。该类使用默认属性和方法(例如存储桶)创建一个 S3 存储桶。 addLifeCycle规则 () ,它向存储桶添加生命周期规则。
L3 构造 - 第 3 层或 L3 构造称为 模式 。L3 结构旨在帮助您完成中的常见任务 AWS,通常涉及多种资源。它们甚至比 L2 构造更具体、更有主见,并为特定的用例服务。例如, aws-ecs-patterns. ApplicationLoadBalancedFargateService 构造表示一种架构,其中包括使用 Application Load Balancer 的 AWS Fargate 容器集群。另一个例子是 aws-apigateway。 LambdaRestApi 构造。该构造表示由 Lambda 函数支持的 Amazon API Gateway API。
随着构造级别的提高,人们对如何使用这些构造做出了更多的假设。这使您可以为高度特定的用例提供具有更有效默认值的接口。
如何创建自己的构造
若要定义自己的构造,必须遵循特定的方法。这是因为所有构造都扩展了
Construct
类。
Construct
类是构造树的构建块。构造是在扩展
Construct
基类的类中实现的。所有构造在初始化时都有三个参数:
作用域
— 构造的父构造或所有者,可以是堆栈,也可以是另一个构造,它决定了它在构造树中的位置。通常,您必须传递
this
(或在 Python 中传递
self
),它表示当前对象的作用域。
id - 在此作用域内必须唯一的标识符。标识符充当当前构造中定义的所有内容的命名空间,用于分配唯一标识,例如资源名称和 CloudFormation 逻辑 ID。
Props — 一组定义构造初始配置的属性。
以下示例演示了如何定义构造。
import { Construct } from 'constructs'; export interface CustomProps { // List all the properties Name: string; export class MyConstruct extends Construct { constructor(scope: Construct, id: string, props: CustomProps) { super(scope, id); // TODO
创建或扩展 L2 构造
L2 构造表示 “云组件”,它封装了创建该 CloudFormation 组件所需的所有内容。L2 构造可以包含一个或多个 AWS 资源,你可以自由地自己定制构造。创建或扩展 L2 构造的好处是,无需重新定义代码即可在 CloudFormation 堆栈中重复使用组件。您只需将构造作为一个类导入。
当与现有构造存在 “是” 关系时,您可以扩展现有构造以添加其他默认功能。最佳做法是重用现有 L2 构造的属性。您可以通过直接在构造函数中修改属性来覆盖属性。
以下示例演示了如何遵循最佳实践,并扩展名为
s3.Bucket
的现有 L2 构造。该扩展建立默认属性,如versioned
、publicReadAccess
、blockPublicAccess
,以确保通过此新构造创建的所有对象(在本例中为 S3 存储桶)将始终设置这些默认值。
import * as s3 from 'aws-cdk-lib/aws-s3'; import { Construct } from 'constructs'; export class MySecureBucket extends s3.Bucket { constructor(scope: Construct, id: string, props?: s3.BucketProps) { super(scope, id, { ...props, versioned: true, publicReadAccess: false, blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL
创建 L3 构造
当与现有构造组合存在 “有” 关系时,组合是更好的选择。组合意味着您在其他现有构造的基础上构建自己的构造。您可以创建自己的模式,将所有资源及其默认值封装在一个可以共享的更高级别的 L3 构造中。创建自己的 L3 构造(模式)的好处是,您可以在堆栈中重用组件,而无需重新定义代码。您只需将构造作为一个类导入。这些模式旨在帮助使用者以简洁的方式,利用有限的知识,根据通用模式预置多种资源。
以下代码示例创建了一个名为的 AWS CDK 构造
ExampleConstruct
。您可以使用此构造作为模板来定义云组件。
import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; export interface ExampleConstructProps { //insert properties you wish to expose export class ExampleConstruct extends Construct { constructor(scope: Construct, id: string, props: ExampleConstructProps) { super(scope, id); //Insert the AWS components you wish to integrate
以下示例说明如何在 AWS CDK 应用程序或堆栈中导入新创建的构造。
import { ExampleConstruct } from './lib/construct-name';
以下示例演示了如何实例化从基类扩展的构造实例。
import { ExampleConstruct } from './lib/construct-name'; new ExampleConstruct(this, 'newConstruct', { //insert props which you exposed in the interface `ExampleConstructProps`
有关更多信息,请参阅 Wor AWS CDK k
shop 文档中的 AWS CDK 研讨会。 你可以使用中的逃生舱口 AWS CDK 来上升一个抽象级别,这样你就可以访问较低级别的构造。逃生舱口用于扩展当前版本中未公开 AWS 但在中 CloudFormation可用的要素的构造。
我们建议您在以下情况下使用转义孵化:
可通过 AWS 服务 使用某项功能 CloudFormation,但没有针对该功能的
Construct
构造。一项 AWS 服务 功能可通过获得, CloudFormation 并且有该服务的
Construct
构造,但这些构造尚未公开该功能。由于Construct
构造是 “手工” 开发的,因此它们有时可能落后于 CloudFormation 资源结构。以下示例代码显示了使用转义孵化的常见用例。在此示例中,尚未在更高级别的构造中实现的功能用于添加
httpPutResponseHopLimit
以自动缩放LaunchConfiguration
。
const launchConfig = autoscaling.onDemandASG.node.findChild("LaunchConfig") as CfnLaunchConfiguration; launchConfig.metadataOptions = { httpPutResponseHopLimit: autoscalingConfig.httpPutResponseHopLimit|| 2
上述代码示例显示了以下工作流程:
使用 L2 构造来定义您的
AutoScalingGroup
。L2 构造不支持更新httpPutResponseHopLimit
,因此您必须使用逃生舱口。您可以访问 L2
AutoScalingGroup
构造上的node.defaultChild
属性,将其强制转换为CfnLaunchConfiguration
资源。您现在可以在 L1
CfnLaunchConfiguration
上设置launchConfig.metadataOptions
属性。自定义资源
您可以使用自定义资源在模板中编写自定义配置逻辑,这些逻辑将在您创建、更新(如果您更改了自定义资源)或删除堆栈时 CloudFormation 运行。例如,如果您想包含中没有的资源,则可以使用自定义资源 AWS CDK。这样,您仍然可以在一个堆栈中管理所有相关资源。
构建自定义资源涉及编写 Lambda 函数,来响应资源的 CREATE、UPDATE 和 DELETE 生命周期事件。如果您的自定义资源只能进行一次 API 调用,请考虑使用AwsCustomResource
构造。这使得在 CloudFormation 部署期间可以执行任意 SDK 调用。否则,我们建议您编写自己的 Lambda 函数来执行必须完成的工作。 有关自定义资源的更多信息,请参阅 CloudFormation 文档中的自定义资源。有关如何使用自定义资源的示例,请参阅上的自定义资源
存储库 GitHub。 以下示例说明如何创建自定义资源类来启动 Lambda 函数并发送 CloudFormation 成功或失败信号。
import cdk = require('aws-cdk-lib'); import customResources = require('aws-cdk-lib/custom-resources'); import lambda = require('aws-cdk-lib/aws-lambda'); import { Construct } from 'constructs'; import fs = require('fs'); export interface MyCustomResourceProps { * Message to echo message: string; export class MyCustomResource extends Construct { public readonly response: string; constructor(scope: Construct, id: string, props: MyCustomResourceProps) { super(scope, id); const fn = new lambda.SingletonFunction(this, 'Singleton', { uuid: 'f7d4f730-4ee1-11e8-9c2d-fa7ae01bbebc', code: new lambda.InlineCode(fs.readFileSync('custom-resource-handler.py', { encoding: 'utf-8' })), handler: 'index.main', timeout: cdk.Duration.seconds(300), runtime: lambda.Runtime.PYTHON_3_6, const provider = new customResources.Provider(this, 'Provider', { onEventHandler: fn, const resource = new cdk.CustomResource(this, 'Resource', { serviceToken: provider.serviceToken, properties: props, this.response = resource.getAtt('Response').toString();
以下示例显示了自定义资源的主要逻辑。
def main(event, context): import logging as log import cfnresponse log.getLogger().setLevel(log.INFO) # This needs to change if there are to be multiple resources in the same stack physical_id = 'TheOnlyCustomResource' log.info('Input event: %s', event) # Check if this is a Create and we're failing Creates if event['RequestType'] == 'Create' and event['ResourceProperties'].get('FailCreate', False): raise RuntimeError('Create failure requested') # Do the thing message = event['ResourceProperties']['Message'] attributes = { 'Response': 'You said "%s"' % message cfnresponse.send(event, context, cfnresponse.SUCCESS, attributes, physical_id) except Exception as e: log.exception(e) # cfnresponse's error message is always "see CloudWatch" cfnresponse.send(event, context, cfnresponse.FAILED, {}, physical_id)
以下示例显示 AWS CDK 堆栈如何调用自定义资源。
import cdk = require('aws-cdk-lib'); import { MyCustomResource } from './my-custom-resource'; * A stack that sets up MyCustomResource and shows how to get an attribute from it class MyStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const resource = new MyCustomResource(this, 'DemoResource', { message: 'CustomResource says hello', // Publish the custom resource output new cdk.CfnOutput(this, 'ResponseMessage', { description: 'The message that came back from the Custom Resource', value: resource.response