

這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護，並於 2023 年 6 月 1 日結束支援。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# AWS 合成時的 CDK 政策驗證
<a name="policy-validation-synthesis"></a>

## 合成時的政策驗證
<a name="policy-validation"></a>

如果您或您的組織使用任何政策驗證工具，例如 [AWS CloudFormation Guard](https://docs.aws.amazon.com/cfn-guard/latest/ug/what-is-guard.html) 或 [OPA](https://www.openpolicyagent.org/)，來定義 AWS CloudFormation 範本的限制，您可以在合成時將其與 AWS CDK 整合。透過使用適當的政策驗證外掛程式，您可以讓 AWS CDK 應用程式在合成後立即針對您的政策檢查 generated AWS CloudFormation 範本。如果有任何違規，合成將會失敗，而報告將會列印到主控台。

 AWS CDK 在合成時間執行的驗證會在部署生命週期的某個時間點驗證控制項，但不會影響在合成之外發生的動作。範例包括直接在主控台或透過服務 APIs採取的動作。它們在合成後不會抵抗 AWS CloudFormation 範本的更改。應以更授權的方式驗證相同規則集的一些其他機制應獨立設定，例如 [AWS CloudFormation hooks](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/hooks.html) 或 [AWS Config](https://docs.aws.amazon.com/config/latest/developerguide/WhatIsConfig.html)。不過， AWS CDK 在開發期間評估規則集的能力仍然很有用，因為它可以提高偵測速度和開發人員生產力。

 AWS CDK 政策驗證的目標是將開發期間所需的設定數量降至最低，並盡可能輕鬆地進行。

**注意**  
先前的`Beta1`界面 （例如 `IPolicyValidationPluginBeta1`、 `PolicyValidationPluginReportBeta1`和 上的 `policyValidationBeta1` 屬性`Stage`) 已漸進到穩定的無尾碼對等項目 （例如 `IPolicyValidationPlugin`、 `PolicyValidationPluginReport`)。`Beta1` 界面已棄用，但會繼續運作。註冊驗證外掛程式的建議方式現在是透過 `Validations`類別，而不是 `policyValidationBeta1` 屬性。

## 適用於應用程式開發人員
<a name="for-application-developers"></a>

### 新增驗證外掛程式
<a name="adding-validation-plugins"></a>

若要在應用程式中使用一或多個驗證外掛程式，請使用 `Validations`類別：

```
import { Validations } from 'aws-cdk-lib';
import { CfnGuardValidator } from '@cdklabs/cdk-validator-cfnguard';

const app = new App();

// Add a validation plugin to the entire app
Validations.of(app).addPlugins(new CfnGuardValidator());

// Or add to a particular stage
const prodStage = new Stage(app, 'ProdStage');
Validations.of(prodStage).addPlugins(new CfnGuardValidator());
```

合成後，會以這種方式註冊的所有外掛程式都會立即被叫用，以驗證在您定義的範圍內產生的所有範本。特別是，如果您在 `App` 物件中註冊範本，則所有範本都必須經過驗證。

**警告**  
除了修改雲端組件之外，外掛程式還可以執行 AWS CDK 應用程式可以執行的任何操作。他們可以從檔案系統讀取資料、存取網路等。身為外掛程式的消費者，您有責任確認使用是否安全。

### 新增警告和錯誤
<a name="adding-warnings-and-errors"></a>

`Validations` 類別也提供將自訂警告和錯誤新增至建構的方法：

```
import { Validations } from 'aws-cdk-lib';

const bucket = new s3.Bucket(this, 'MyBucket');

// Add a warning
Validations.of(bucket).addWarning('MyWarningId', 'This bucket does not have versioning enabled');

// Add an error (will cause synthesis to fail)
Validations.of(bucket).addError('MyErrorId', 'This bucket must have encryption enabled');
```

### 確認警告
<a name="acknowledging-warnings"></a>

如果您想要隱藏特定警告，請使用 `acknowledge`方法：

```
import { Validations } from 'aws-cdk-lib';

Validations.of(myConstruct).acknowledge({ id: 'MyWarningId', reason: 'This is acceptable for our use case' });
```

`acknowledge` 方法接受具有 `id`和 的`Acknowledgment`物件`reason`。`id` 使用`::`分隔符號來分隔驗證來源字首與規則名稱 （例如 `annotation::MyWarning`或 `cdknag::AwsSolutions-S1`)。如果您提供不含 的裸機 ID`::`，則會自動新增`annotation::`字首。

### AWS CloudFormation Guard 外掛程式
<a name="cfnguard-plugin"></a>

使用 [https://github.com/cdklabs/cdk-validator-cfnguard](https://github.com/cdklabs/cdk-validator-cfnguard) 外掛程式可讓您使用 [AWS CloudFormation Guard](https://github.com/aws-cloudformation/cloudformation-guard) 來執行政策驗證。`CfnGuardValidator` 外掛程式隨附一組內建的 [AWS Control Tower 主動控制](https://docs.aws.amazon.com/controltower/latest/userguide/proactive-controls.html)。您可以在[專案文件中](https://github.com/cdklabs/cdk-validator-cfnguard/blob/main/README.md)找到目前的規則集。如[合成時政策驗證](#policy-validation)中所述，我們建議組織使用 [AWS CloudFormation 勾點](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/hooks.html)設定更權威的驗證方法。

對於 [AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html) 客戶，這些相同的主動控制可以部署到整個組織。當您在 AWS Control Tower 環境中啟用 AWS Control Tower 主動控制時，這些控制可以停止部署透過 AWS CloudFormation 部署的不合規資源。如需受管主動控制及其運作方式的詳細資訊，請參閱 [AWS Control Tower 文件](https://docs.aws.amazon.com/controltower/latest/userguide/proactive-controls.html)。

這些 AWS CDK 綁定控制項和受管 AWS Control Tower 主動控制項最好一起使用。在此案例中，您可以使用與 AWS Control Tower 雲端環境中作用中的相同主動控制來設定此驗證外掛程式。然後，您可以透過`cdk synth`在本機執行 ，快速獲得對 AWS CDK 應用程式將通過 AWS Control Tower 控制項的信心。

### 驗證報告
<a name="validation-report"></a>

當您合成 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 格式的報告，`@aws-cdk/core:validationReportJson`請透過 CLI 使用 啟用報告，或直接將其傳遞給應用程式：

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

或者，您可以使用專案目錄中的 `cdk.json`或 `cdk.context.json` 檔案來設定此內容索引鍵/值對 （請參閱[內容值和 AWS CDK](context.md))。

如果您選擇 JSON 格式， AWS CDK 會將政策驗證報告列印到雲端組件目錄中名為 `policy-validation-report.json` 的檔案。對於預設的人類可讀格式，報告將列印到標準輸出。

## 對於外掛程式作者
<a name="plugin-authors"></a>

### 外掛程式
<a name="plugins"></a>

 AWS CDK 核心架構負責註冊和叫用外掛程式，然後顯示格式化的驗證報告。外掛程式的責任是做為 AWS CDK 架構和政策驗證工具之間的轉譯層。外掛程式可以使用 AWS CDK 支援的任何語言建立。如果您要建立可能由多種語言使用的外掛程式，建議您在 中建立外掛程式，`TypeScript`以便您可以使用 JSII 在每個 AWS CDK 語言中發佈外掛程式。

### 建立外掛程式
<a name="creating-plugins"></a>

 AWS CDK 核心模組與政策工具之間的通訊協定由 `IPolicyValidationPlugin` 介面定義。若要建立新的外掛程式，您必須撰寫實作此界面的類別。您需要實作兩件事：外掛程式名稱 （透過覆寫 `name` 屬性） 和 `validate()`方法。

框架將呼叫 `validate()`，傳遞 `IPolicyValidationContext` 物件。要驗證的範本位置由 提供`templatePaths`。外掛程式應該會傳回 的執行個體`PolicyValidationPluginReport`。此物件代表使用者在合成結束時收到的報告。

```
validate(context: IPolicyValidationContext): PolicyValidationPluginReport {
  // 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`[指令碼](https://docs.npmjs.com/cli/v9/using-npm/scripts)。

### 處理豁免
<a name="handling-exemptions"></a>

如果您的組織具有處理豁免的機制，則可以將其實作為驗證器外掛程式的一部分。

說明可能豁免機制的範例案例：
+ 組織具有不允許公有 Amazon S3 儲存貯體的規則，*但*在某些情況下除外。
+ 開發人員正在建立屬於其中一個案例的 Amazon S3 儲存貯體，並請求豁免 （例如建立票證）。
+ 安全工具知道如何從註冊豁免的內部系統讀取

在此案例中，開發人員會在內部系統中請求例外狀況，然後需要某種方法來「註冊」該例外狀況。將 新增至 防護外掛程式範例，您可以透過篩選掉內部票證系統中具有相符豁免的違規，來建立處理豁免的外掛程式。

如需範例實作，請參閱現有的外掛程式。
+  [@cdklabs/cdk-validator-cfnguard](https://github.com/cdklabs/cdk-validator-cfnguard) 