

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

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

# 使用 CDK Blueprints 配置构造
<a name="blueprints"></a>

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

Blueprints 由*属性注入*提供支持，这是 AWS CDK [v2.196.0](https://github.com/aws/aws-cdk/releases/tag/v2.196.0) 中引入的一种机制，允许您在实例化时修改构造属性。蓝图是属性注入器的集合，其中每个属性注入器都针对特定 L2 构造指定最佳配置。蓝图代表组织的整体最佳实践。

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

有关详细实现信息，请参阅[属性注入 RFC](https://github.com/aws/aws-cdk-rfcs/blob/main/text/0693-property-injection.md)。

## Blueprints 的关键组件
<a name="blueprints-key-pieces"></a>

Blueprints 是属性注入器的集合，用于在实例化构造时将默认属性应用于构造。属性注入器是实现 `IPropertyInjector` 接口的组件，它会拦截构造的创建，并在创建构造之前修改或添加属性。
+  **IPropertyInjector** - ` [IPropertyInjector](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IPropertyInjector.html) ` 定义一种注入 props 中未指定的额外属性的方法。它特定于一个 L2 构造，并对该构造的属性进行操作。
+  **PropertyInjectors** - ` [PropertyInjectors](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.PropertyInjectors.html) ` 是附加到构造树的注入器的集合。注入器可以附加到任何构造，但实际上我们预计大多数注入器都会附加到 `App`、`Stage` 或 `Stack`。

## Blueprints 的常见使用案例
<a name="blueprints-use-cases"></a>

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

 **安全标准**   
+ 确保所有 Amazon S3 存储桶均已启用服务器端加密。
+ 将所有安全组配置为默认阻止公共访问。
+ 对 AWS Lambda 函数应用 AWS Identity and Access Management (IAM) 最低权限原则。
+ 强制所有网络通信使用 SSL。

 **卓越运营**   
+ 为所有 AWS Lambda 函数配置标准化日志记录。
+ 对资源应用一致的标签策略。
+ 设置默认监控和警报阈值。
+ 实施标准的日志和备份保留策略。

 **成本优化**。  
+ 根据环境配置合适的实例大小。
+ 应用具有组织默认值的自动扩缩策略。
+ 设置 Amazon S3 存储桶的生命周期规则，以便将对象转换到更经济的存储类别。
+ 配置数据库的默认预置吞吐量。

 **合规性要求**   
+ 为受监管数据实施所需的加密设置。
+ 根据数据保留要求应用必要的备份策略。
+ 配置符合安全要求的 Amazon VPC 默认设置。
+ 确保资源具有成本分配所需的标签。

 **开发人员工作效率**   
+ 提供合理的默认值，减少对样板代码的需求。
+ 使用内置注入器创建组织特定的 Stack 类。
+ 通过可重用的注入器在团队间共享最佳实践。
+ 通过将组织知识编码到代码中来简化部署过程。

## 开始使用 Blueprints
<a name="blueprints-getting-started"></a>

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

首先，为 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');
```

## 最佳实践
<a name="blueprints-best-practices"></a>
+ 将默认属性放在 `…​originalProps` 之前以允许覆盖。
+ 将强制属性放在 `…​originalProps` 之后以防止覆盖。
+ 创建资源时，请使用跳过标志以防止无限递归。例如，请参阅*属性注入 RFC* 中的 [What happens when you need to create a accessLogBucket for a Bucket?](https://github.com/aws/aws-cdk-rfcs/blob/main/text/0693-property-injection.md#what-happens-when-you-need-to-create-a-accesslogbucket-for-a-bucket)。
+ 添加日志记录以进行调试。
+ 使用 CDK 上下文启用/禁用注入器以进行测试。

有关属性注入的更多详细信息，包括实现详细信息、故障排除技巧和参考信息，请参阅[属性注入 RFC](https://github.com/aws/aws-cdk-rfcs/blob/main/text/0693-property-injection.md)。