添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
创建或扩展构造 - AWS 规范性指导

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

创建或扩展构造

什么是构造

构造是 AWS CDK 应用程序的基本构建块。结构可以表示单个 AWS 资源,例如亚马逊简单存储服务 (Amazon S3) Service 存储桶,也可以是由多个相关资源组成的更高级别的抽象。 AWS 构造的组件可以包括具有相关计算能力的工作队列,或者具有监控资源和控制面板的计划作业。 AWS CDK 包括一个名为 “构造库” 的 AWS 构造集合。该库包含每个 AWS 服务的构造。您可以使用 C onstruc t Hub 发现来自 AWS第三方和开源 AWS CDK 社区的其他构造。

构造有哪些不同的类型

有三种不同类型的构造: 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 构造。该扩展建立默认属性,如 versionedpublicReadAccessblockPublicAccess,以确保通过此新构造创建的所有对象(在本例中为 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