

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

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

# 針對常見的 AWS CDK 問題進行故障診斷
<a name="troubleshooting"></a>

本主題說明如何針對 AWS CDK 的下列問題進行疑難排解。
+  [更新 AWS CDK 之後， AWS CDK Toolkit (CLI) 會回報與 AWS 建構程式庫不相符](#troubleshooting-toolkit) 
+  [部署 AWS CDK 堆疊時，我收到 NoSuchBucket 錯誤](#troubleshooting-nobucket) 
+  [部署 AWS CDK 堆疊時，我會收到禁止： null 訊息](#troubleshooting-forbidden-null) 
+  [合成 AWS CDK 堆疊時，我會收到訊息 --app 在 cdk.json 或 \~/.cdk.json 的命令列中為必要](#troubleshooting-app-required) 
+  [合成 AWS CDK 堆疊時，我會收到錯誤，因為 AWS CloudFormation 範本包含太多資源](#troubleshooting-resource-count) 
+  [我為 Auto Scaling 群組或 VPC 指定了三個 （或更多） 可用區域，但只部署在兩個](#troubleshooting-availability-zones) 
+  [當我發出 cdk 銷毀時，不會刪除我的 S3 儲存貯體 DynamoDB 資料表或其他資源](#troubleshooting-resource-not-deleted) 

## 更新 AWS CDK 之後， AWS CDK Toolkit (CLI) 會回報與 AWS 建構程式庫不相符
<a name="troubleshooting-toolkit"></a>

 AWS CDK Toolkit 的版本 （提供 `cdk`命令） 必須至少等於主要 AWS 建構程式庫模組 的版本`aws-cdk-lib`。Toolkit 旨在回溯相容。工具組的最新 2.x 版本可與程式庫的任何 1.x 或 2.x 版本搭配使用。因此，我們建議您全域安裝此元件並保持最新狀態。

```
npm update -g aws-cdk
```

如果您需要使用多個版本的 AWS CDK Toolkit，請在專案資料夾本機安裝特定版本的工具組。

如果您使用的是 TypeScript 或 JavaScript，您的專案目錄已包含 CDK Toolkit 的版本控制本機副本。

如果您使用的是其他語言，請使用 `npm` 安裝 AWS CDK Toolkit，省略 `-g`旗標並指定所需的版本。例如：

```
npm install aws-cdk@2.0
```

若要執行本機安裝的 AWS CDK Toolkit，請使用 命令`npx aws-cdk`，而非僅使用 `cdk`。例如：

```
npx aws-cdk deploy MyStack
```

 `npx aws-cdk` 如果存在， 會執行 AWS CDK Toolkit 的本機版本。當專案沒有本機安裝時，它會回到全域版本。您可能會發現設定 shell 別名以確保`cdk`一律以這種方式叫用 相當方便。

**Example**  

```
alias cdk="npx aws-cdk"
```

```
doskey cdk=npx aws-cdk $*
```

## 部署 AWS CDK 堆疊時，我收到`NoSuchBucket`錯誤
<a name="troubleshooting-nobucket"></a>

您的 AWS 環境尚未啟動，因此沒有在部署期間保留資源的 Amazon S3 儲存貯體。您可以使用下列命令建立預備儲存貯體和其他必要的資源：

```
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```

為了避免產生意外 AWS 費用， AWS CDK 不會自動引導任何環境。您必須明確引導要部署到的每個環境。

根據預設，引導資源會在目前 AWS CDK 應用程式中堆疊所使用的區域或區域中建立。或者，它們是在本機 AWS 設定檔中指定的區域中建立 （由 設定`aws configure`)，使用該設定檔的 帳戶。您可以在命令列上指定不同的帳戶和區域，如下所示。（如果您不在應用程式的 目錄中，則必須指定帳戶和區域。)

```
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```

如需詳細資訊，請參閱 [AWS CDK 引導](bootstrapping.md)。

## 部署 AWS CDK 堆疊時，我會收到`forbidden: null`一則訊息
<a name="troubleshooting-forbidden-null"></a>

您正在部署需要引導資源的堆疊，但使用缺少寫入許可的 IAM 角色或帳戶。（部署包含資產或合成大於 50K 的 AWS CloudFormation 範本的堆疊時，會使用預備儲存貯體。) 使用有權`s3:*`對錯誤訊息中提到的儲存貯體執行動作的帳戶或角色。

## 合成 AWS CDK 堆疊時，我會收到訊息 `--app is required either in command-line, in cdk.json or in ~/.cdk.json`
<a name="troubleshooting-app-required"></a>

此訊息通常表示您在發出 時不在 AWS CDK 專案的主目錄中`cdk synth`。`cdk.json` 此目錄中的檔案由 `cdk init`命令建立，包含執行 （進而合成） AWS CDK 應用程式所需的命令列。例如，對於 TypeScript 應用程式，預設值`cdk.json`看起來像這樣：

```
{
  "app": "npx ts-node bin/my-cdk-app.ts"
}
```

我們建議您只在專案的主目錄中發出`cdk`命令，讓 AWS CDK 工具組可以在`cdk.json`那裡找到並成功執行您的應用程式。

如果因為某些原因而不切實際， AWS CDK Toolkit 會在其他兩個位置尋找應用程式的命令列：
+ 主目錄中的 `cdk.json`中
+ 使用 `-a`選項在`cdk synth`命令本身上

例如，您可以從 TypeScript 應用程式合成堆疊，如下所示。

```
cdk synth --app "npx ts-node my-cdk-app.ts" MyStack
```

## 合成 AWS CDK 堆疊時，我會收到錯誤，因為 AWS CloudFormation 範本包含太多資源
<a name="troubleshooting-resource-count"></a>

 AWS CDK 會產生並部署 AWS CloudFormation 範本。 AWS CloudFormation 對堆疊可包含的資源數量有硬性限制。使用 AWS CDK，您可以比預期更快地達到此限制。

**注意**  
在此寫入時， AWS CloudFormation 資源限制為 500。如需目前的資源限制，請參閱 [AWS CloudFormation 配額](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html)。

 AWS Construct Library 的高階意圖型建構會自動佈建記錄、金鑰管理、授權和其他用途所需的任何輔助資源。例如，授予另一個資源存取權會產生相關服務通訊所需的任何 IAM 物件。

根據我們的經驗，實際使用以意圖為基礎的建構會產生每個建構 1–5 AWS CloudFormation 資源，但這可能會有所不同。對於無伺服器應用程式，每個 API 端點通常有 5–8 個 AWS 資源。

模式代表更高層級的抽象，可讓您以更少的程式碼定義更多 AWS 資源。範例中的 AWS CDK 程式碼：例如，使用 CDK 建立 Fargate 服務會產生超過 50 AWS CloudFormation 資源，同時只定義三個建構！ [AWSAWS](ecs-example.md)

超過 AWS CloudFormation 資源限制是 AWS CloudFormation 合成期間的錯誤。如果您的堆疊超過限制的 80%， AWS CDK 會發出警告。您可以在堆疊上設定 `maxResources` 屬性來使用不同的限制，或將 `maxResources`設定為 0 來停用驗證。

**提示**  
您可以使用下列公用程式指令碼，取得合成輸出中資源的確切計數。（由於每個 AWS CDK 開發人員都需要 Node.js，因此指令碼會以 JavaScript.)  

```
// rescount.js - count the resources defined in a stack
// invoke with: node rescount.js <path-to-stack-json>
// e.g. node rescount.js cdk.out/MyStack.template.json

import * as fs from 'fs';
const path = process.argv[2];

if (path) fs.readFile(path, 'utf8', function(err, contents) {
  console.log(err ? `${err}` :
  `${Object.keys(JSON.parse(contents).Resources).length} resources defined in ${path}`);
}); else console.log("Please specify the path to the stack's output .json file");
```

隨著堆疊的資源計數接近限制，請考慮重新建構以減少堆疊包含的資源數量：例如，透過合併一些 Lambda 函數，或將您的堆疊分成多個堆疊。CDK 支援[堆疊之間的參考](resources.md#resource-stack)，因此您可以將應用程式的功能以對您最有意義的方式分成不同的堆疊。

**注意**  
 AWS CloudFormation 專家通常會建議使用巢狀堆疊做為資源限制的解決方案。 AWS CDK 透過 [NestedStack](stacks.md#stack-nesting) 建構支援此方法。

## 我為 Auto Scaling 群組或 VPC 指定了三個 （或更多） 可用區域，但只部署在兩個
<a name="troubleshooting-availability-zones"></a>

若要取得您請求的可用區域數量，請在堆疊的 `env` 屬性中指定帳戶和區域。如果您未同時指定兩者， AWS CDK 預設會將堆疊合成為與環境無關。然後，您可以使用 AWS CloudFormation 將堆疊部署到特定區域。由於某些區域只有兩個可用區域，與環境無關的範本不會使用超過兩個。

**注意**  
在過去，區域偶爾只會啟動一個可用區域。與環境無關的 AWS CDK 堆疊無法部署到此類區域。不過，在此撰寫中，所有 AWS 區域至少有兩個 AZs。

您可以透過覆寫堆疊的 [availabilityZones](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones) (Python：`availability_zones`) 屬性來變更此行為，以明確指定要使用的區域。

如需在合成時指定堆疊帳戶和區域，同時保留部署到任何區域的彈性的詳細資訊，請參閱 [AWS CDK 的環境](environments.md)。

## 當我發出 時，不會刪除我的 S3 儲存貯體、DynamoDB 資料表或其他資源 `cdk destroy`
<a name="troubleshooting-resource-not-deleted"></a>

根據預設，可包含使用者資料的資源具有 的 `removalPolicy`(Python：`removal_policy`) 屬性`RETAIN`，且在堆疊銷毀時不會刪除資源。反之，資源會從堆疊中孤立。然後，您必須在堆疊銷毀後手動刪除資源。在您這麼做之前，重新部署堆疊會失敗。這是因為在部署期間建立新資源的名稱與孤立資源的名稱衝突。

如果您將資源的移除政策設定為 `DESTROY`，則會在堆疊銷毀時刪除該資源。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';

export class CdkTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });
  }
}
```

```
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

class CdkTestStack extends cdk.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY
    });
  }
}

module.exports = { CdkTestStack }
```

```
import aws_cdk as cdk
from constructs import Construct
import aws_cdk.aws_s3 as s3

class CdkTestStack(cdk.stack):
    def __init__(self, scope: Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        bucket = s3.Bucket(self, "Bucket",
            removal_policy=cdk.RemovalPolicy.DESTROY)
```

```
software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;
import software.constructs;

public class CdkTestStack extends Stack {
    public CdkTestStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkTestStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Bucket.Builder.create(this, "Bucket")
                .removalPolicy(RemovalPolicy.DESTROY).build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

public CdkTestStack(Construct scope, string id, IStackProps props) : base(scope, id, props)
{
    new Bucket(this, "Bucket", new BucketProps {
        RemovalPolicy = RemovalPolicy.DESTROY
    });
}
```

**注意**  
 AWS CloudFormation 無法刪除非空白的 Amazon S3 儲存貯體。如果您將 Amazon S3 儲存貯體的移除政策設定為 `DESTROY`，且其包含資料，則嘗試銷毀堆疊將會失敗，因為無法刪除儲存貯體。您可以讓 AWS CDK 在嘗試銷毀儲存貯體中的物件之前，先將儲存貯體的`autoDeleteObjects`道具設定為 `true`。