这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
本主题介绍如何排查 AWS CDK的以下问题。
更新后 AWS CDK, AWS CDK 工具包 (CLI) 报告与 AWS 构造库不匹配
AWS CDK 工具包(提供cdk
命令)的版本必须至少等于主 AWS 构造库模块的版本aws-cdk-lib
。该工具包旨在向后兼容。该工具包的最新 2.x 版本可与该库的任何 1.x 或 2.x 版本一起使用。为此,我们建议您全局安装此组件并使其保持最新版本。
npm update -g aws-cdk
如果您需要使用该 AWS CDK 工具包的多个版本,请在您的项目文件夹中本地安装该工具包的特定版本。
如果您使用的是 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
会很方便。
alias 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 角色或账户缺少写入权限。(部署包含资产或合成大于 50 K AWS CloudFormation 模板的堆栈时,会使用暂存存储桶。) 使用有权对错误消息中提及的存储桶执行 s3:*
操作的账户或角色。
(返回列表)
合成 AWS CDK 堆栈时,我收到的消息是 --app is
required either in command-line, in cdk.json or in ~/.cdk.json
这条消息通常意味着当你发布问题时,你不在 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
中 -
在
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 配额。
C AWS onstruct 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 支持这种方法。
(返回列表)
我为自动扩缩组或 VPC 指定了三个(或更多)可用区,但只部署在两个可用区中
要获取您请求的可用区数量,请在堆栈的 env
属性中指定账户和区域。如果未同时指定两者,则默认情况下 AWS CDK,会将堆栈合成为与环境无关的堆栈。然后,您可以使用将堆栈部署到特定区域 AWS CloudFormation。由于某些区域只有两个可用区,因此与环境无关的模板不会使用两个以上的区域。
注意
过去,区域偶尔会只启动一个可用区。与环境无关的 AWS CDK 堆栈无法部署到此类区域。但是,在撰写本文时,所有 AWS 地区都至少有两个 AZs。
您可以通过覆盖堆栈的 availablilityZones
(Python:availability_zones
)属性来更改此行为,从而明确指定要使用的区域。
有关在合成时指定堆栈的账户和区域,同时保留部署到任何区域的灵活性的更多信息,请参阅 的环境 AWS CDK。
(返回列表)
在我发出 cdk destroy
命令时,我的 S3 存储桶、DynamoDB 表或其他资源没有被删除
默认情况下,可以包含用户数据的资源具有 RETAIN
的 removalPolicy
(Python:removal_policy
)属性,并且在销毁堆栈不会删除该资源。相反,该资源从堆栈中孤立出来。然后,必须在销毁堆栈后手动删除该资源。除非手动删除该资源,否则重新部署堆栈将失败。这是因为部署期间创建的新资源的名称与孤立资源的名称冲突。
如果您将资源的删除策略设置为 DESTROY
,则将在销毁堆栈时删除该资源。
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,
});
}
}
注意
AWS CloudFormation 无法删除非空的 Amazon S3 存储桶。如果您将 Amazon S3 存储桶的删除策略设置为 DESTROY
,并且其中包含数据,则尝试销毁该堆栈将失败,因为无法删除该存储桶。您可以将存储桶的 autoDeleteObjects
prop 设置为 true
,从而让 AWS CDK 在尝试销毁存储桶之前删除其中的对象。
(返回列表)