在合成时进行 AWS CDK 策略验证 - AWS Cloud Development Kit (AWS CDK) v2

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

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

在合成时进行 AWS CDK 策略验证

在合成时进行策略验证

如果您或您的组织使用任何策略验证工具(例如 AWS CloudFormation GuardOPA)在 AWS CloudFormation 模板上定义约束,则可以在合成时将其与 AWS CDK 集成。使用适当的策略验证插件,就可以让 AWS CDK 应用程序在合成后立即根据您的策略对生成的 AWS CloudFormation 模板进行检查。如果有任何违规行为,合成将失败,控制台将打印一份报告。

AWS CDK 在合成时执行的验证可在部署生命周期的某一时刻验证控制功能,但它们不能影响合成之外发生的操作。示例包含了直接在控制台中或通过服务 API 执行的操作。它们无法阻止合成后对 AWS CloudFormation 模板的改变。应独立设置一些其他机制来更权威地验证相同的规则集,例如 AWS CloudFormation 钩子AWS Config。尽管如此,AWS CDK 在开发过程中评估规则集的功能仍然很有用,因为这有助于提高检测速度和开发人员的工作效率。

AWS CDK 策略验证的目标是尽量减少开发过程中所需的设置量,并使其尽可能简单。

注意

此功能被视为实验性质,插件 API 和验证报告的格式将来都有可能发生变化。

对于应用程序开发人员

要在应用程序中使用一个或多个验证插件,请使用 StagepolicyValidationBeta1 属性:

import { CfnGuardValidator } from '@cdklabs/cdk-validator-cfnguard'; const app = new App({ policyValidationBeta1: [ new CfnGuardValidator() ], }); // only apply to a particular stage const prodStage = new Stage(app, 'ProdStage', { policyValidationBeta1: [...], });

合成后,将立即调用以这种方式注册的所有插件,来验证在您定义的范围内生成的所有模板。特别是,如果在 App 对象中注册模板,则所有模板都将接受验证。

警告

除了修改云程序集之外,插件可以执行 AWS CDK 应用程序可以执行的任何操作。插件可以从文件系统中读取数据、访问网络等。作为插件的使用者,您有责任验证其使用是否安全。

AWS CloudFormation Guard 插件

采用 CfnGuardValidator 插件,您可以使用 AWS CloudFormation Guard 来执行策略验证。CfnGuardValidator 插件中内置了一组精选的 AWS Control Tower 主动控制功能。可在项目文档中找到当前规则集。如 在合成时进行策略验证 中所述,我们建议组织使用 AWS CloudFormation 钩子来设置更权威的验证方法。

对于 AWS Control Tower 客户,可以在整个组织中部署这些相同的主动控制功能。当您在 AWS Control Tower 环境中启用 AWS Control Tower 主动控制功能时,这些控制功能可以停止部署通过 AWS CloudFormation 部署的不合规资源。有关托管的主动控制功能及其工作原理的更多信息,请参阅 AWS Control Tower 文档

最好将这些 AWS CDK 捆绑的控制功能和托管的 AWS Control Tower 主动控制功能一起使用。在这种情况下,您可以使用相同的主动控制功能来配置此验证插件,这些控制功能在 AWS Control Tower 云环境中处于活动状态。然后,您可以通过在本地运行 cdk synth 来快速确信您的 AWS CDK 应用程序将通过 AWS Control Tower 控制。

验证报告

合成 AWS CDK 应用程序时,将调用验证器插件并打印结果。下面显示了一个示例报告。

Validation Report (CfnGuardValidator) ------------------------------------- (Summary) ╔═══════════╤════════════════════════╗ ║ Status │ failure ║ ╟───────────┼────────────────────────╢ ║ Plugin │ CfnGuardValidator ║ ╚═══════════╧════════════════════════╝ (Violations) Ensure S3 Buckets are encrypted with a KMS CMK (1 occurrences) Severity: medium Occurrences: - Construct Path: MyStack/MyCustomL3Construct/Bucket - Stack Template Path: ./cdk.out/MyStack.template.json - Creation Stack: └── MyStack (MyStack) │ Library: aws-cdk-lib.Stack │ Library Version: 2.50.0 │ Location: Object.<anonymous> (/home/johndoe/tmp/cdk-tmp-app/src/main.ts:25:20) └── MyCustomL3Construct (MyStack/MyCustomL3Construct) │ Library: N/A - (Local Construct) │ Library Version: N/A │ Location: new MyStack (/home/johndoe/tmp/cdk-tmp-app/src/main.ts:15:20) └── Bucket (MyStack/MyCustomL3Construct/Bucket) │ Library: aws-cdk-lib/aws-s3.Bucket │ Library Version: 2.50.0 │ Location: new MyCustomL3Construct (/home/johndoe/tmp/cdk-tmp-app/src/main.ts:9:20) - Resource Name: amzn-s3-demo-bucket - Locations: > BucketEncryption/ServerSideEncryptionConfiguration/0/ServerSideEncryptionByDefault/SSEAlgorithm Recommendation: Missing value for key `SSEAlgorithm` - must specify `aws:kms` How to fix: > Add to construct properties for `cdk-app/MyStack/Bucket` `encryption: BucketEncryption.KMS` Validation failed. See above reports for details

默认情况下,将以人类可读的格式打印报告。如果您想要 JSON 格式的报告,请通过 CLI 使用 @aws-cdk/core:validationReportJson 进行启用,或将其直接传递给应用程序:

const app = new App({ context: { '@aws-cdk/core:validationReportJson': true }, });

或者,您可以使用项目目录中的 cdk.jsoncdk.context.json 文件来设置此上下文键值对(请参阅上下文值和 AWS CDK)。

如果您选择 JSON 格式,则 AWS CDK 会将策略验证报告打印到云程序集目录中名为 policy-validation-report.json 的文件中。对于默认的人类可读格式,报告将打印为标准输出。

对于插件作者

插件

AWS CDK 核心框架负责注册和调用插件,然后显示格式化的验证报告。该插件的职责是充当 AWS CDK 框架和策略验证工具之间的转换层。可以用 AWS CDK 支持的任何语言创建插件。如果您正在创建可能使用多种语言的插件,则建议使用 TypeScript 来创建该插件,这样您就可以使用 JSII 以每种 AWS CDK 语言发布该插件。

创建插件

AWS CDK 核心模块和策略工具之间的通信协议由 IPolicyValidationPluginBeta1 接口进行定义。要创建新插件,必须编写一个可以实现此接口的类。您需要实现两件事:插件名称(通过覆盖 name 属性)和 validate() 方法。

框架将调用 validate(),同时传递一个 IValidationContextBeta1 对象。待验证模板的位置由 templatePaths 给出。该插件应返回一个 ValidationPluginReportBeta1 实例。此对象表示用户在合成结束时将收到的报告。

validate(context: IPolicyValidationContextBeta1): PolicyValidationReportBeta1 { // First read the templates using context.templatePaths... // ...then perform the validation, and then compose and return the report. // Using hard-coded values here for better clarity: return { success: false, violations: [{ ruleName: 'CKV_AWS_117', description: 'Ensure that AWS Lambda function is configured inside a VPC', fix: 'https://docs.bridgecrew.io/docs/ensure-that-aws-lambda-function-is-configured-inside-a-vpc-1', violatingResources: [{ resourceName: 'MyFunction3BAA72D1', templatePath: '/home/johndoe/myapp/cdk.out/MyService.template.json', locations: 'Properties/VpcConfig', }], }], }; }

请注意,不允许插件修改云程序集中的任何内容。任何这样的尝试都将导致合成失败。

如果您的插件依赖于外部工具,请记住,某些开发人员可能尚未在他们的工作站中安装该工具。为了尽量减少摩擦,我们强烈建议您随插件包提供一些安装脚本,以实现整个过程的自动化。更好的做法是,在安装软件包时运行该脚本。例如,使用 npm,您可以将其添加到 package.json 文件中的 postinstall 脚本中。

处理豁免

如果您的组织有处理豁免的机制,则可以将其作为验证器插件的一部分来实现。

以下示例场景说明了可能的豁免机制:

  • 组织有一条规则,即除非在某些情况下,否则不允许使用公有 Amazon S3 存储桶。

  • 开发人员正在创建属于以上其中一种情况的 Amazon S3 存储桶,并请求豁免(例如创建工单)。

  • 安全工具知道如何从注册了豁免的内部系统中进行读取

在这种情况下,开发人员将在内部系统中请求异常,然后需要以某种方式“注册”该异常。在警卫插件示例的基础上,您可以创建一个处理豁免的插件,方法是筛选出在内部票务系统中具有匹配豁免的违规行为。

请参阅现有插件获取实现示例。