使用 CDK Blueprints 配置构造 - AWS Cloud Development Kit (AWS CDK) v2

这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。

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

使用 CDK Blueprints 配置构造

使用 AWS CDK Blueprints 在整个组织中标准化和分发 L2 构造配置。借助 Blueprints,您可以确保 AWS 资源按照组织标准和最佳实践进行一致配置。例如,您可以自动为所有 Amazon S3 存储桶启用加密,将特定日志记录配置应用于所有 AWS Lambda 函数,或对所有安全组强制执行标准安全规则。

Blueprints 由属性注入提供支持,这是 AWS CDK v2.196.0 中引入的一种机制,允许您在实例化时修改构造属性。蓝图是属性注入器的集合,其中每个属性注入器都针对特定 L2 构造指定最佳配置。蓝图代表组织的整体最佳实践。

蓝图不是合规性强制执行机制。如有需要,开发人员仍可覆盖默认设置。为了严格执行合规性,除了 Blueprints 之外,还可以考虑使用 AWS CloudFormation Guard、服务控制策略或 CDK 方面。

有关详细实现信息,请参阅属性注入 RFC

Blueprints 的关键组件

Blueprints 是属性注入器的集合,用于在实例化构造时将默认属性应用于构造。属性注入器是实现 IPropertyInjector 接口的组件,它会拦截构造的创建,并在创建构造之前修改或添加属性。

  • IPropertyInjector - IPropertyInjector 定义一种注入 props 中未指定的额外属性的方法。它特定于一个 L2 构造,并对该构造的属性进行操作。

  • PropertyInjectors - PropertyInjectors 是附加到构造树的注入器的集合。注入器可以附加到任何构造,但实际上我们预计大多数注入器都会附加到 AppStageStack

Blueprints 的常见使用案例

您可以使用 CDK Blueprints 来标准化 AWS 资源的诸多方面。下面是一些常见使用案例:

安全标准
  • 确保所有 Amazon S3 存储桶均已启用服务器端加密。

  • 将所有安全组配置为默认阻止公共访问。

  • 对 AWS Lambda 函数应用 AWS Identity and Access Management (IAM) 最低权限原则。

  • 强制所有网络通信使用 SSL。

卓越运营
  • 为所有 AWS Lambda 函数配置标准化日志记录。

  • 对资源应用一致的标签策略。

  • 设置默认监控和警报阈值。

  • 实施标准的日志和备份保留策略。

成本优化
  • 根据环境配置合适的实例大小。

  • 应用具有组织默认值的自动扩缩策略。

  • 设置 Amazon S3 存储桶的生命周期规则,以便将对象转换到更经济的存储类别。

  • 配置数据库的默认预置吞吐量。

合规性要求
  • 为受监管数据实施所需的加密设置。

  • 根据数据保留要求应用必要的备份策略。

  • 配置符合安全要求的 Amazon VPC 默认设置。

  • 确保资源具有成本分配所需的标签。

开发人员工作效率
  • 提供合理的默认值,减少对样板代码的需求。

  • 使用内置注入器创建组织特定的 Stack 类。

  • 通过可重用的注入器在团队间共享最佳实践。

  • 通过将组织知识编码到代码中来简化部署过程。

开始使用 Blueprints

以下示例简要介绍了如何创建和使用属性注入器:

首先,为 Amazon S3 存储桶创建属性注入器:

import { IPropertyInjector, InjectionContext } from 'aws-cdk-lib'; import { Bucket, BucketProps, BlockPublicAccess } from 'aws-cdk-lib/aws-s3'; export class SecureBucketDefaults implements IPropertyInjector { public readonly constructUniqueId: string; constructor() { this.constructUniqueId = Bucket.PROPERTY_INJECTION_ID; } public inject(originalProps: BucketProps, _context: InjectionContext): BucketProps { return { // Set security defaults blockPublicAccess: BlockPublicAccess.BLOCK_ALL, enforceSSL: true, // Include original props to allow overrides ...originalProps, }; } }

然后,在 CDK 应用程序中使用注入器:

import { App, Stack } from 'aws-cdk-lib'; import { Bucket } from 'aws-cdk-lib/aws-s3'; import { SecureBucketDefaults } from './secure-bucket-defaults'; // Attach injectors when creating the App const app = new App({ propertyInjectors: [new SecureBucketDefaults()] }); const stack = new Stack(app, 'MyStack'); // This bucket automatically gets the default properties const myBucket = new Bucket(stack, 'MyBucket');

或者,您可以使用 PropertyInjectors.of() 方法:

import { App, Stack, PropertyInjectors } from 'aws-cdk-lib'; import { SecureBucketDefaults } from './secure-bucket-defaults'; const app = new App(); PropertyInjectors.of(app).add(new SecureBucketDefaults()); const stack = new Stack(app, 'MyStack'); const myBucket = new Bucket(stack, 'MyBucket');

最佳实践

  • 将默认属性放在 …​originalProps 之前以允许覆盖。

  • 将强制属性放在 …​originalProps 之后以防止覆盖。

  • 创建资源时,请使用跳过标志以防止无限递归。例如,请参阅属性注入 RFC 中的 What happens when you need to create a accessLogBucket for a Bucket?

  • 添加日志记录以进行调试。

  • 使用 CDK 上下文启用/禁用注入器以进行测试。

有关属性注入的更多详细信息,包括实现详细信息、故障排除技巧和参考信息,请参阅属性注入 RFC