这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
在本教程中,您将 AWS Cloud Development Kit (AWS CDK) 使用创建简单的无服务器 Hello World 实现基本 API 后端的应用程序,包括以下内容:
-
亚马逊 API Gateway REST API— 提供一个 HTTP 端点,用于通过以下方式调用您的函数 HTTP GET 请求。
-
AWS Lambda 函数 — 使用调用时返回
Hello World!
消息的函数 HTTP 端点。 -
集成和权限-您的资源相互交互和执行操作(例如向 Amazon CloudWatch 写入日志)的配置详细信息和权限。
下图显示此应用程序的组件:

在本教程中,您将按照以下步骤创建应用程序并与之交互:
-
创建 AWS CDK 项目。
-
使用构造库中的 L2 构造定义 Lambda 函数和 API Gateway REST API。 AWS
-
将您的应用程序部署到 AWS Cloud。
-
在中与您的应用程序交互 AWS Cloud。
-
从 AWS Cloud中删除示例应用程序。
主题
先决条件
开始教程前,请完成以下步骤:
-
创建 AWS 账户 并安装并配置 AWS Command Line Interface (AWS CLI)。
-
安装 Node.js 以及 npm.
-
使用
npm install -g aws-cdk
全局安装 CDK Toolkit。
有关更多信息,请参阅 开始使用 AWS CDK。
我们还建议您初步了解以下内容:
-
那是什么 AWS CDK?获取对 AWS CDK. 的基本介绍
-
学习 AWS CDK 核心概念,了解 AWS CDK核心概念的概述。
步骤 1:创建 CDK 项目
在此步骤中,您将使用创建新的 CDK 项目 AWS CDK CLI cdk init
命令。
创建 CDK 项目
-
从您选择的起始目录,在您的计算机上创建并导航到名为
cdk-hello-world
的项目目录:$
mkdir cdk-hello-world && cd cdk-hello-world
-
使用
cdk init
命令以您的首选编程语言创建新项目:$
cdk init --language typescript
安装 AWS CDK 库:
$
npm install aws-cdk-lib constructs
CDK CLI 创建具有以下结构的项目:
cdk-hello-world ├── .git ├── .gitignore ├── .npmignore ├── README.md ├── bin │ └── cdk-hello-world.ts ├── cdk.json ├── jest.config.js ├── lib │ └── cdk-hello-world-stack.ts ├── node_modules ├── package-lock.json ├── package.json ├── test │ └── cdk-hello-world.test.ts └── tsconfig.json
CDK CLI 自动创建包含单个堆栈的 CDK 应用程序。根据 App
类来创建 CDK 应用程序实例。以下内容是 CDK 应用程序文件的一部分:
位于 bin/cdk-hello-world.ts
中:
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { CdkHelloWorldStack } from '../lib/cdk-hello-world-stack';
const app = new cdk.App();
new CdkHelloWorldStack(app, 'CdkHelloWorldStack', {
});
步骤 2:创建 Lambda 函数
在您的 CDK 项目中,创建一个包含新 hello.js
文件的 lambda
目录。以下是示例:
在项目的根目录中运行以下命令:
$
mkdir lambda && cd lambda
$
touch hello.js
现在应将以下内容添加到您的 CDK 项目中:
cdk-hello-world
└── lambda
└── hello.js
注意
为了简化本教程,我们使用了 JavaScript 适用于所有 CDK 编程语言的 Lambda 函数。
向新创建的文件中添加以下内容来定义您的 Lambda 函数:
exports.handler = async (event) => {
return {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: JSON.stringify({ message: "Hello, World!" }),
};
};
步骤 3:定义构造
在此步骤中,您将使用 AWS CDK L2 结构来定义 Lambda 和 API Gateway 资源。
打开定义您 CDK 堆栈的项目文件。您将修改此文件以定义您的构造。以下是启动堆栈文件的示例:
位于 lib/cdk-hello-world-stack.ts
中:
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class CdkHelloWorldStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Your constructs will go here
}
}
在此文件中, AWS CDK 正在执行以下操作:
-
从
Stack
类中实例化您的 CDK 堆栈实例。 -
导入
Constructs
基类并将其作为堆栈实例的作用域或父类提供。
定义您的 Lambda 函数资源
要定义您的 Lambda 函数资源,请从 AWS 构造库中导入并使用 aws-lambda
L2 构造。
按如下方式修改您的堆栈文件:
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// Import Lambda L2 construct
import * as lambda from 'aws-cdk-lib/aws-lambda';
export class CdkHelloWorldStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Define the Lambda function resource
const helloWorldFunction = new lambda.Function(this, 'HelloWorldFunction', {
runtime: lambda.Runtime.NODEJS_20_X, // Choose any supported Node.js runtime
code: lambda.Code.fromAsset('lambda'), // Points to the lambda directory
handler: 'hello.handler', // Points to the 'hello' file in the lambda directory
});
}
}
在此,您将创建 Lambda 函数资源并定义以下属性:
-
runtime
:函数运行的环境。在这里,我们使用 Node.js version 20.x. -
code
:本地计算机上函数代码的路径。 -
handler
:包含您函数代码的特定文件名称。
定义你的 API Gateway REST API 资源
定义你的 API Gateway REST API 资源,您可以从构造库中导入和使用 aws-apigateway
L2 AWS 构造。
按如下方式修改您的堆栈文件:
// ...
//Import API Gateway L2 construct
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
export class CdkHelloWorldStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// ...
// Define the API Gateway resource
const api = new apigateway.LambdaRestApi(this, 'HelloWorldApi', {
handler: helloWorldFunction,
proxy: false,
});
// Define the '/hello' resource with a GET method
const helloResource = api.root.addResource('hello');
helloResource.addMethod('GET');
}
}
在这里,您可以创建一个 API Gateway REST API 资源,以及以下内容:
-
两者之间的集成 REST API 以及您的 Lambda 函数,允许该 API 调用您的函数。这包括创建 Lambda 权限资源。
-
添加到 API 端点根目录的名为
hello
的新资源或路径。这会创建一个新的终端节点,/hello
为你的基础增光添彩 URL. -
hello
资源的 GET 方法。在向/hello
端点发送 GET 请求时,会调用 Lambda 函数并返回其响应。
步骤 4:为部署准备应用程序
在此步骤中,您可以通过构建应用程序来准备部署应用程序(如有必要),并使用以下命令执行基本验证 AWS CDK CLI cdk synth
命令。
如有必要,请构建您的应用程序:
在项目的根目录中运行以下命令:
$
npm run build
运行cdk synth
以根据你的 CDK 代码合成一个 AWS CloudFormation 模板。通过使用 L2 结构,可以获得便利 Lambda 函数与之间的交互所需的许多配置细节 AWS CloudFormation REST API 由为您提供。 AWS CDK
在项目的根目录中运行以下命令:
$
cdk synth
注意
如果您收到如下错误,请确认您是否位于 cdk-hello-world
目录中并重试:
--app is required either in command-line, in cdk.json or in ~/.cdk.json
如果成功, AWS CDK CLI 将在中输出 AWS CloudFormation 模板 YAML 在命令提示符处格式化。A JSON 格式化的模板也保存在cdk.out
目录中。
以下是 AWS CloudFormation 模板的输出示例:
Resources:
HelloWorldFunctionServiceRoleunique-identifier
:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Version: "2012-10-17"
ManagedPolicyArns:
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Metadata:
aws:cdk:path: CdkHelloWorldStack/HelloWorldFunction/ServiceRole/Resource
HelloWorldFunctionunique-identifier
:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket:
Fn::Sub: cdk-unique-identifier
-assets-${AWS::AccountId}-${AWS::Region}
S3Key: unique-identifier
.zip
Handler: hello.handler
Role:
Fn::GetAtt:
- HelloWorldFunctionServiceRoleunique-identifier
- Arn
Runtime: nodejs20.x
DependsOn:
- HelloWorldFunctionServiceRoleunique-identifier
Metadata:
aws:cdk:path: CdkHelloWorldStack/HelloWorldFunction/Resource
aws:asset:path: asset.unique-identifier
aws:asset:is-bundled: false
aws:asset:property: Code
HelloWorldApiunique-identifier
:
Type: AWS::ApiGateway::RestApi
Properties:
Name: HelloWorldApi
Metadata:
aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Resource
HelloWorldApiDeploymentunique-identifier
:
Type: AWS::ApiGateway::Deployment
Properties:
Description: Automatically created by the RestApi construct
RestApiId:
Ref: HelloWorldApiunique-identifier
DependsOn:
- HelloWorldApihelloGETunique-identifier
- HelloWorldApihellounique-identifier
Metadata:
aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Deployment/Resource
HelloWorldApiDeploymentStageprod012345ABC
:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId:
Ref: HelloWorldApiDeploymentunique-identifier
RestApiId:
Ref: HelloWorldApiunique-identifier
StageName: prod
Metadata:
aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/DeploymentStage.prod/Resource
HelloWorldApihellounique-identifier
:
Type: AWS::ApiGateway::Resource
Properties:
ParentId:
Fn::GetAtt:
- HelloWorldApiunique-identifier
- RootResourceId
PathPart: hello
RestApiId:
Ref: HelloWorldApiunique-identifier
Metadata:
aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Default/hello/Resource
HelloWorldApihelloGETApiPermissionCdkHelloWorldStackHelloWorldApiunique-identifier
:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName:
Fn::GetAtt:
- HelloWorldFunctionunique-identifier
- Arn
Principal: apigateway.amazonaws.com
SourceArn:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":execute-api:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- ":"
- Ref: HelloWorldApi9E278160
- /
- Ref: HelloWorldApiDeploymentStageprodunique-identifier
- /GET/hello
Metadata:
aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Default/hello/GET/ApiPermission.CdkHelloWorldStackHelloWorldApiunique-identifier
.GET..hello
HelloWorldApihelloGETApiPermissionTestCdkHelloWorldStackHelloWorldApiunique-identifier
:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName:
Fn::GetAtt:
- HelloWorldFunctionunique-identifier
- Arn
Principal: apigateway.amazonaws.com
SourceArn:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":execute-api:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- ":"
- Ref: HelloWorldApiunique-identifier
- /test-invoke-stage/GET/hello
Metadata:
aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Default/hello/GET/ApiPermission.Test.CdkHelloWorldStackHelloWorldApiunique-identifier
.GET..hello
HelloWorldApihelloGETunique-identifier
:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: GET
Integration:
IntegrationHttpMethod: POST
Type: AWS_PROXY
Uri:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":apigateway:"
- Ref: AWS::Region
- :lambda:path/2015-03-31/functions/
- Fn::GetAtt:
- HelloWorldFunctionunique-identifier
- Arn
- /invocations
ResourceId:
Ref: HelloWorldApihellounique-identifier
RestApiId:
Ref: HelloWorldApiunique-identifier
Metadata:
aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Default/hello/GET/Resource
CDKMetadata:
Type: AWS::CDK::Metadata
Properties:
Analytics: v2:deflate64:unique-identifier
Metadata:
aws:cdk:path: CdkHelloWorldStack/CDKMetadata/Default
Condition: CDKMetadataAvailable
Outputs:
HelloWorldApiEndpointunique-identifier
:
Value:
Fn::Join:
- ""
- - https://
- Ref: HelloWorldApiunique-identifier
- .execute-api.
- Ref: AWS::Region
- "."
- Ref: AWS::URLSuffix
- /
- Ref: HelloWorldApiDeploymentStageprodunique-identifier
- /
Conditions:
CDKMetadataAvailable:
Fn::Or:
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- af-south-1
- Fn::Equals:
- Ref: AWS::Region
- ap-east-1
- Fn::Equals:
- Ref: AWS::Region
- ap-northeast-1
- Fn::Equals:
- Ref: AWS::Region
- ap-northeast-2
- Fn::Equals:
- Ref: AWS::Region
- ap-south-1
- Fn::Equals:
- Ref: AWS::Region
- ap-southeast-1
- Fn::Equals:
- Ref: AWS::Region
- ap-southeast-2
- Fn::Equals:
- Ref: AWS::Region
- ca-central-1
- Fn::Equals:
- Ref: AWS::Region
- cn-north-1
- Fn::Equals:
- Ref: AWS::Region
- cn-northwest-1
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- eu-central-1
- Fn::Equals:
- Ref: AWS::Region
- eu-north-1
- Fn::Equals:
- Ref: AWS::Region
- eu-south-1
- Fn::Equals:
- Ref: AWS::Region
- eu-west-1
- Fn::Equals:
- Ref: AWS::Region
- eu-west-2
- Fn::Equals:
- Ref: AWS::Region
- eu-west-3
- Fn::Equals:
- Ref: AWS::Region
- il-central-1
- Fn::Equals:
- Ref: AWS::Region
- me-central-1
- Fn::Equals:
- Ref: AWS::Region
- me-south-1
- Fn::Equals:
- Ref: AWS::Region
- sa-east-1
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- us-east-1
- Fn::Equals:
- Ref: AWS::Region
- us-east-2
- Fn::Equals:
- Ref: AWS::Region
- us-west-1
- Fn::Equals:
- Ref: AWS::Region
- us-west-2
Parameters:
BootstrapVersion:
Type: AWS::SSM::Parameter::Value<String>
Default: /cdk-bootstrap/hnb659fds/version
Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
CheckBootstrapVersion:
Assertions:
- Assert:
Fn::Not:
- Fn::Contains:
- - "1"
- "2"
- "3"
- "4"
- "5"
- Ref: BootstrapVersion
AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
使用 L2 构造,您可以定义一些属性来配置资源,并使用辅助方法将其集成在一起。 AWS CDK 配置配置应用程序所需的大部分 AWS CloudFormation 资源和属性。
步骤 5:部署应用程序
在此步骤中,您将使用 AWS CDK CLI cdk deploy
命令来部署您的应用程序。 AWS CDK 与该 AWS CloudFormation 服务配合使用以配置您的资源。
重要
在部署之前,您必须对 AWS 环境进行一次性引导。有关说明,请参阅 引导您的环境以用于 AWS CDK。
在项目的根目录中运行以下命令。如果系统提示,请确认更改:
$
cdk deploy
✨ Synthesis time: 2.44s ... Do you wish to deploy these changes (y/n)?y
部署完成后, AWS CDK CLI 将输出您的终端节点 URL。复制此 URL 以供下一步使用。以下是示例:
... ✅ HelloWorldStack ✨ Deployment time: 45.37s Outputs: HelloWorldStack.HelloWorldApiEndpoint
unique-identifier
= https://<api-id>
.execute-api.<region>
.amazonaws.com/prod/ Stack ARN: arn:aws:cloudformation:region
:account-id
:stack/HelloWorldStack/unique-identifier
...
步骤 6:与您的应用程序交互
在此步骤中,您将向 API 端点发起 GET 请求并接收 Lambda 函数响应。
找到上一步中的端点 URL 并添加 /hello
路径。然后使用浏览器或命令提示符向 API 端点发送 GET 请求。以下是示例:
$
curl https://
{"message":"Hello World!"}%<api-id>
.execute-api.<region>
.amazonaws.com/prod/hello
祝贺您,您已使用 AWS CDK成功创建、部署了应用程序并与之交互!
步骤 7:删除应用程序
在此步骤中,您将使用 AWS CDK CLI 从中删除您的应用程序 AWS Cloud。
要删除您的应用程序,请运行 cdk destroy
。系统提示时,请确认删除应用程序的请求:
$
cdk destroy
Are you sure you want to delete: CdkHelloWorldStack (y/n)?y
CdkHelloWorldStack: destroying... [1/1] ... ✅ CdkHelloWorldStack: destroyed
故障排除
错误:{“message”: “Internal server error”}%
在调用已部署的 Lambda 函数时,您会收到此错误。此错误可能由多种原因引起。
进一步排查问题
使用 AWS CLI 来调用您的 Lambda 函数。
-
修改您的堆栈文件以捕获已部署的 Lambda 函数名称的输出值。以下是示例:
... class CdkHelloWorldStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Define the Lambda function resource // ... new CfnOutput(this, 'HelloWorldFunctionName', { value: helloWorldFunction.functionName, description: 'JavaScript Lambda function' }); // Define the API Gateway resource // ...
-
再次部署您的应用程序。的 AWS CDK CLI 将输出您部署的 Lambda 函数名称的值:
$
cdk deploy
✨ Synthesis time: 0.29s ... ✅ CdkHelloWorldStack ✨ Deployment time: 20.36s Outputs: ... CdkHelloWorldStack.HelloWorldFunctionName = CdkHelloWorldStack-HelloWorldFunctionunique-identifier
... -
使用在中调 AWS CLI 用您的 Lambda 函数 AWS Cloud 并将响应输出到文本文件:
$
aws lambda invoke --function-name CdkHelloWorldStack-HelloWorldFunction
unique-identifier
output.txt -
检查
output.txt
以查看您的结果。
- 可能的原因:堆栈文件中对 API Gateway 资源的定义不正确。
-
如果
output.txt
显示 Lambda 函数响应成功,则问题可能出在您定义 API Gateway REST API 的方式上。直接 AWS CLI 调用您的 Lambda,而不是通过您的终端节点。检查您的代码以确保其符合本教程。然后再次部署。 - 可能的原因:堆栈文件中对 Lambda 资源的定义不正确。
-
如果
output.txt
返回错误,则问题可能与您定义 Lambda 函数的方式有关。检查您的代码以确保其符合本教程。然后再次部署。