常見 AWS CDK 問題的疑難 - AWS Cloud Development Kit (AWS CDK) V2

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

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

常見 AWS CDK 問題的疑難

本主題說明如何疑難排解下列問題 AWS CDK。

更新之後 AWS CDK, AWS CDK Toolkit (CLI) 會報告與 AWS 建構程式庫不相符

AWS CDK Toolkit (提供cdk指令) 的版本必須至少等於主要「 AWS 建構程式庫」模組的版本aws-cdk-lib。該工具包的目的是向後兼容。該工具包的最新 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 工具組」的本機版本 (如果存在)。當項目沒有本地安裝時,它會退回到全局版本。您可能會發現設置 shell 別名以確保cdk始終以這種方式調用它很方便。

macOS/Linux
alias cdk="npx aws-cdk"
Windows
doskey cdk=npx aws-cdk $*

(返回列表)

部署 AWS CDK 堆疊時,我收到NoSuchBucket錯誤訊息

您的 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 引導

(返回列表)

部署 AWS CDK 堆疊時,我收到一forbidden: null則訊息

您正在部署需要啟動程序資源的堆疊,但使用的是缺少寫入權限的IAM角色或帳戶。(當部署包含資產的堆棧或合成大於 50K 的 AWS CloudFormation 模板時,會使用臨時存儲桶。) 使用具有對錯誤訊息中提到的值區執s3:*行動作之權限的帳號或角色。

(返回列表)

合成 AWS CDK 堆棧時,我收到消息 --app is required either in command-line, in cdk.json or in ~/.cdk.json

此消息通常意味著您在發出問題時不在 AWS CDK 項目的主目錄中cdk synth。由cdk init命令創建的此目錄cdk.json中的文件包含運行(並從而合成) AWS CDK 應用程序所需的命令行。例如,對於 TypeScript 應用程序,默認值cdk.json看起來像這樣:

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

我們建議您只在專案的主目錄中發出cdk指令,以便 AWS CDK 工具組可以cdk.json在該處找到並成功執行您的應用程式。

如果由於某種原因這不實際,則 AWS CDK 工具包會在其他兩個位置查找應用程序的命令行:

  • cdk.json在您的主目錄

  • cdk synth命令本身上使用該-a選項

例如,您可以按照以下方式從 TypeScript 應用程序合成堆棧。

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

(返回列表)

當合成 AWS CDK 堆棧時,我收到一個錯誤,因為 AWS CloudFormation 模板包含太多資源

會 AWS CDK 產生並部署 AWS CloudFormation 範本。 AWS CloudFormation 對堆棧可以包含的資源數量有硬性限制。使用時 AWS CDK,您可以比預期的更快速地執行此限制。

注意

在撰寫本文時, AWS CloudFormation 資源限制為 500。請參閱AWS CloudFormation 配額以瞭解目前的資源限制。

Con AWS struct Library 的較高層級的意向型結構會自動佈建記錄、金鑰管理、授權及其他用途所需的任何輔助資源。例如,授與一個資源存取權給另一個資源會產生相關服務進行通訊所需的任何IAM物件。

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

模式代表較高層級的抽象,可讓您以更少的程式碼定義更多 AWS 資源。例如範例: AWS Fargate 使用 AWS CDK,中的 AWS CDK 代碼生成 50 多個 AWS CloudFormation 資源,而只定義三個構造!

超過資 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支持堆棧之間的引用,因此您可以以對您最有意義的任何方式將應用程序的功能分成不同的堆棧。

注意

AWS CloudFormation 專家經常建議使用嵌套堆棧作為資源限制的解決方案。通過NestedStack構造 AWS CDK 支持這種方法。

(返回列表)

我為 Auto Scaling 群組指定了三個 (或更多) 可用區域VPC,但它只部署在兩個

若要取得您要求的可用區域數目,請在堆疊的內env容中指定帳戶和區域。如果您未同時指定兩者,依預設 AWS CDK,會將堆疊合成為與環境無關的情況。然後,您可以使用將堆疊部署到特定區域 AWS CloudFormation。由於某些區域只有兩個可用區域,因此不受環境限制的範本使用不超過兩個。

注意

在過去,區域偶爾會啟動只有一個可用區域。與環境無關的 AWS CDK 堆疊無法部署到此類區域。然而,在撰寫本文時,所有 AWS 區域至少都有兩個AZs。

您可以通過覆蓋堆棧的 availablilityZones(Python:availability_zones)屬性來顯式指定要使用的區域來更改此行為。

如需在合成時指定堆疊帳戶和區域的詳細資訊,同時保留部署到任何區域的彈性,請參閱適用的環境 AWS CDK

(返回列表)

當我發出問題時,我的 S3 儲存貯體、DynamoDB 資料表或其他資源並未刪除 cdk destroy

默認情況下,可以包含用戶數據的資源具有removalPolicy(Python:removal_policy)屬性RETAIN,並且在堆棧銷毀時不會刪除該資源。相反,該資源是從堆棧中孤立的。然後,您必須在堆棧銷毀後手動刪除資源。在您這麼做之前,重新部署堆疊會失敗。這是因為部署期間所建立的新資源名稱與孤立資源的名稱衝突。

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

TypeScript
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, }); } }
JavaScript
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 }
Python
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)
Java
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(); } }
C#
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 prop 設定為將其銷毀true

(返回列表)