建立無伺服器的 Hello World 應用程式 - AWS Cloud Development Kit (AWS CDK) V2

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

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

建立無伺服器的 Hello World 應用程式

在本教學課程中,您可以透過建立下列項目 AWS Cloud Development Kit (AWS CDK) 來建立簡單的無伺服器Hello World應用程式,以實作基本 API 後端:

  • Amazon API Gateway REST API — 提供用於透過HTTP GET請求叫用函數的 HTTP 端點。

  • AWS Lambda function — 使用HTTP端點叫用時傳回Hello World!訊息的函數。

  • 整合和許可 — 讓您的資源彼此互動並執行動作 (例如將日誌寫入 Amazon) 的組態詳細資訊和許可 CloudWatch。

下圖顯示此應用程式的組件:


      當您將 GET 要求傳送至 API Gateway 端點時叫用的 Lambda 函數圖表。

對於本教學課程,您將完成以下操作:

  1. 建立 AWS CDK 專案。

  2. 使用建構程式庫中的 L2 AWS 建構來定義 Lambda 函數和 API Gateway REST API。

  3. 將您的應用程式部署到 AWS 雲端.

  4. 與中的應用程式互動 AWS 雲端。

  5. 從中刪除範例應用程式 AWS 雲端。

必要條件

開始本教學課程之前,請完成下列動作:

  • 創建一個 AWS 帳戶 並安裝和配置 AWS Command Line Interface (AWS CLI)。

  • 安裝Node.js和npm。

  • 在全球範圍內安裝 CDK 工具組,使用npm install -g aws-cdk.

如需詳細資訊,請參閱 開始使用 AWS CDK

我們還建議對以下內容有基本的了解:

步驟 1:建立 CDK 專案

在此步驟中,您要使用 AWS CDK CLIcdk init指令建立新 CDK 專案。

若要建立 CDK 專案
  1. 從您選擇的起始目錄中,創建並導航到計算機cdk-hello-world上名為的項目目錄:

    $ mkdir cdk-hello-world && cd cdk-hello-world
  2. 使用指cdk init令以您偏好的程式設計語言建立新專案:

    TypeScript
    $ cdk init --language typescript

    安裝 AWS CDK 程式庫:

    $ npm install aws-cdk-lib constructs
    JavaScript
    $ cdk init --language javascript

    安裝 AWS CDK 程式庫:

    $ npm install aws-cdk-lib constructs
    Python
    $ cdk init --language python

    啟用虛擬環境:

    $ source .venv/bin/activate

    安裝 AWS CDK 庫和項目依賴關係:

    (.venv)$ python3 -m pip install -r requirements.txt
    Java
    $ cdk init --language java

    安裝 AWS CDK 庫和項目依賴關係:

    $ mvn package
    C#
    $ cdk init --language csharp

    安裝 AWS CDK 庫和項目依賴關係:

    $ dotnet restore src
    Go
    $ cdk init --language go

    安裝項目依賴關係:

    $ go mod tidy

    CDK CLI 創建具有以下結構的項目:

    TypeScript
    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
    JavaScript
    cdk-hello-world ├── .git ├── .gitignore ├── .npmignore ├── README.md ├── bin │ └── cdk-hello-world.js ├── cdk.json ├── jest.config.js ├── lib │ └── cdk-hello-world-stack.js ├── node_modules ├── package-lock.json ├── package.json └── test └── cdk-hello-world.test.js
    Python
    cdk-hello-world ├── .git ├── .gitignore ├── .venv ├── README.md ├── app.py ├── cdk.json ├── cdk_hello_world │ ├── __init__.py │ └── cdk_hello_world_stack.py ├── requirements-dev.txt ├── requirements.txt ├── source.bat └── tests
    Java
    cdk-hello-world ├── .git ├── .gitignore ├── README.md ├── cdk.json ├── pom.xml ├── src │ ├── main │ │ └── java │ │ └── com │ │ └── myorg │ │ ├── CdkHelloWorldApp.java │ │ └── CdkHelloWorldStack.java └── target
    C#
    cdk-hello-world ├── .git ├── .gitignore ├── README.md ├── cdk.json └── src ├── CdkHelloWorld │ ├── CdkHelloWorld.csproj │ ├── CdkHelloWorldStack.cs │ ├── GlobalSuppressions.cs │ └── Program.cs └── CdkHelloWorld.sln
    Go
    cdk-hello-world ├── .git ├── .gitignore ├── README.md ├── cdk-hello-world.go ├── cdk-hello-world_test.go ├── cdk.json └── go.mod

CDK CLI 會自動建立包含單一堆疊的 CDK 應用程式。CDK 應用程序實例是從App類創建的。以下是 CDK 應用程式檔案的一部分:

TypeScript

位於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', { });
JavaScript

位於bin/cdk-hello-world.js

#!/usr/bin/env node const cdk = require('aws-cdk-lib'); const { CdkHelloWorldStack } = require('../lib/cdk-hello-world-stack'); const app = new cdk.App(); new CdkHelloWorldStack(app, 'CdkHelloWorldStack', { });
Python

位於app.py

#!/usr/bin/env python3 import os import aws_cdk as cdk from cdk_hello_world.cdk_hello_world_stack import CdkHelloWorldStack app = cdk.App() CdkHelloWorldStack(app, "CdkHelloWorldStack",) app.synth()
Java

位於src/main/java/.../CdkHelloWorldApp.java

package com.myorg; import software.amazon.awscdk.App; import software.amazon.awscdk.Environment; import software.amazon.awscdk.StackProps; import java.util.Arrays; public class JavaApp { public static void main(final String[] args) { App app = new App(); new JavaStack(app, "JavaStack", StackProps.builder() .build()); app.synth(); } }
C#

位於src/CdkHelloWorld/Program.cs

using Amazon.CDK; using System; using System.Collections.Generic; using System.Linq; namespace CdkHelloWorld { sealed class Program { public static void Main(string[] args) { var app = new App(); new CdkHelloWorldStack(app, "CdkHelloWorldStack", new StackProps { }); app.Synth(); } } }
Go

位於cdk-hello-world.go

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) // ... func main() { defer jsii.Close() app := awscdk.NewApp(nil) NewCdkHelloWorldStack(app, "CdkHelloWorldStack", &CdkHelloWorldStackProps{ awscdk.StackProps{ Env: env(), }, }) app.Synth(nil) } func env() *awscdk.Environment { return nil }

步驟 2:建立您的 Lambda 函數

在 CDK 專案中,建立包含新hello.js檔案的lambda目錄。以下是範例:

TypeScript

從項目的根目錄中,運行以下命令:

$ mkdir lambda && cd lambda $ touch hello.js

現在應該將以下內容添加到您的 CDK 項目中:

cdk-hello-world └── lambda └── hello.js
JavaScript

從項目的根目錄中,運行以下命令:

$ mkdir lambda && cd lambda $ touch hello.js

現在應該將以下內容添加到您的 CDK 項目中:

cdk-hello-world └── lambda └── hello.js
Python

從項目的根目錄中,運行以下命令:

$ mkdir lambda && cd lambda $ touch hello.js

現在應該將以下內容添加到您的 CDK 項目中:

cdk-hello-world └── lambda └── hello.js
Java

從項目的根目錄中,運行以下命令:

$ mkdir -p src/main/resources/lambda $ cd src/main/resources/lambda $ touch hello.js

現在應該將以下內容添加到您的 CDK 項目中:

cdk-hello-world └── src └── main └──resources └──lambda └──hello.js
C#

從項目的根目錄中,運行以下命令:

$ mkdir lambda && cd lambda $ touch hello.js

現在應該將以下內容添加到您的 CDK 項目中:

cdk-hello-world └── lambda └── hello.js
Go

從項目的根目錄中,運行以下命令:

$ mkdir lambda && cd lambda $ touch hello.js

現在應該將以下內容添加到您的 CDK 項目中:

cdk-hello-world └── lambda └── hello.js
注意

為了簡化本教程,我們對所有 CDK 編程語言使用 JavaScript 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 堆疊的專案檔案。您將修改此檔案以定義您的建構。以下是起始堆棧文件的示例:

TypeScript

位於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 } }
JavaScript

位於lib/cdk-hello-world-stack.js

const { Stack, Duration } = require('aws-cdk-lib'); const lambda = require('aws-cdk-lib/aws-lambda'); const apigateway = require('aws-cdk-lib/aws-apigateway'); class CdkHelloWorldStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Your constructs will go here } } module.exports = { CdkHelloWorldStack }
Python

位於cdk_hello_world/cdk_hello_world_stack.py

from aws_cdk import Stack from constructs import Construct class CdkHelloWorldStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) // Your constructs will go here
Java

位於src/main/java/.../CdkHelloWorldStack.java

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; public class CdkHelloWorldStack extends Stack { public CdkHelloWorldStack(final Construct scope, final String id) { this(scope, id, null); } public CdkHelloWorldStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Your constructs will go here } }
C#

位於src/CdkHelloWorld/CdkHelloWorldStack.cs

using Amazon.CDK; using Constructs; namespace CdkHelloWorld { public class CdkHelloWorldStack : Stack { internal CdkHelloWorldStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Your constructs will go here } } }
Go

位於cdk-hello-world.go

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) type CdkHelloWorldStackProps struct { awscdk.StackProps } func NewCdkHelloWorldStack(scope constructs.Construct, id string, props *CdkHelloWorldStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // Your constructs will go here return stack } func main() { // ... } func env() *awscdk.Environment { return nil }

在這個文件中, AWS CDK 正在執行以下操作:

  • 您的 CDK 堆棧實例是從類中實例化的Stack

  • Constructs基類被導入並作為堆棧實例的作用域或父級提供。

定義您的 Lambda 函數資源

若要定義 Lambda 函數資源,您可以從「建構程式庫」匯入並使用 aws-lambda L2 AWS 建構。

修改堆棧文件,如下所示:

TypeScript
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 }); } }
JavaScript
const { Stack, Duration } = require('aws-cdk-lib'); // Import Lambda L2 construct const lambda = require('aws-cdk-lib/aws-lambda'); class CdkHelloWorldStack extends Stack { constructor(scope, id, props) { 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 }); } } module.exports = { CdkHelloWorldStack }
Python
from aws_cdk import ( Stack, # Import Lambda L2 construct aws_lambda as _lambda, ) # ... class CdkHelloWorldStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Define the Lambda function resource hello_world_function = _lambda.Function( self, "HelloWorldFunction", runtime = _lambda.Runtime.NODEJS_20_X, # Choose any supported Node.js runtime code = _lambda.Code.from_asset("lambda"), # Points to the lambda directory handler = "hello.handler", # Points to the 'hello' file in the lambda directory )
注意

我們導入aws_lambda模塊,_lambda因為它lambda是中Python的內置標識符。

Java
// ... // Import Lambda L2 construct import software.amazon.awscdk.services.lambda.Code; import software.amazon.awscdk.services.lambda.Function; import software.amazon.awscdk.services.lambda.Runtime; public class CdkHelloWorldStack extends Stack { public CdkHelloWorldStack(final Construct scope, final String id) { this(scope, id, null); } public CdkHelloWorldStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Define the Lambda function resource Function helloWorldFunction = Function.Builder.create(this, "HelloWorldFunction") .runtime(Runtime.NODEJS_20_X) // Choose any supported Node.js runtime .code(Code.fromAsset("src/main/resources/lambda")) // Points to the lambda directory .handler("hello.handler") // Points to the 'hello' file in the lambda directory .build(); } }
C#
// ... // Import Lambda L2 construct using Amazon.CDK.AWS.Lambda; namespace CdkHelloWorld { public class CdkHelloWorldStack : Stack { internal CdkHelloWorldStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Define the Lambda function resource var helloWorldFunction = new Function(this, "HelloWorldFunction", new FunctionProps { Runtime = Runtime.NODEJS_20_X, // Choose any supported Node.js runtime Code = Code.FromAsset("lambda"), // Points to the lambda directory Handler = "hello.handler" // Points to the 'hello' file in the lambda directory }); } } }
Go
package main import ( // ... // Import Lambda L2 construct "github.com/aws/aws-cdk-go/awscdk/v2/awslambda" // ... ) // ... func NewCdkHelloWorldStack(scope constructs.Construct, id string, props *CdkHelloWorldStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // Define the Lambda function resource helloWorldFunction := awslambda.NewFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.FunctionProps{ Runtime: awslambda.Runtime_NODEJS_20_X(), // Choose any supported Node.js runtime Code: awslambda.Code_FromAsset(jsii.String("lambda")), // Points to the lambda directory Handler: jsii.String("hello"), // Points to the 'hello' file in the lambda directory }) return stack } // ...

在這裡,您可以建立 Lambda 函數資源並定義下列屬性:

  • runtime— 函數執行的環境。在這裡,我們使用Node.js版本20.x。

  • code— 本機電腦上函數程式碼的路徑。

  • handler— 包含函數程式碼的特定檔案名稱。

定義您的 API Gateway REST API 資源

若要定義您的 API Gateway REST API 資源,請從「建構程式庫」匯入並使用 aws-apigateway L2 AWS 建構。

修改堆棧文件,如下所示:

TypeScript
// ... //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'); } }
JavaScript
// ... // Import API Gateway L2 construct const apigateway = require('aws-cdk-lib/aws-apigateway'); class CdkHelloWorldStack extends Stack { constructor(scope, id, props) { 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'); }; }; // ...
Python
from aws_cdk import ( # ... # Import API Gateway L2 construct aws_apigateway as apigateway, ) from constructs import Construct class CdkHelloWorldStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # ... # Define the API Gateway resource api = apigateway.LambdaRestApi( self, "HelloWorldApi", handler = hello_world_function, proxy = False, ) # Define the '/hello' resource with a GET method hello_resource = api.root.add_resource("hello") hello_resource.add_method("GET")
Java
// ... // Import API Gateway L2 construct import software.amazon.awscdk.services.apigateway.LambdaRestApi; import software.amazon.awscdk.services.apigateway.Resource; public class CdkHelloWorldStack extends Stack { public CdkHelloWorldStack(final Construct scope, final String id) { this(scope, id, null); } public CdkHelloWorldStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // ... // Define the API Gateway resource LambdaRestApi api = LambdaRestApi.Builder.create(this, "HelloWorldApi") .handler(helloWorldFunction) .proxy(false) // Turn off default proxy integration .build(); // Define the '/hello' resource and its GET method Resource helloResource = api.getRoot().addResource("hello"); helloResource.addMethod("GET"); } }
C#
// ... // Import API Gateway L2 construct using Amazon.CDK.AWS.APIGateway; namespace CdkHelloWorld { public class CdkHelloWorldStack : Stack { internal CdkHelloWorldStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // ... // Define the API Gateway resource var api = new LambdaRestApi(this, "HelloWorldApi", new LambdaRestApiProps { Handler = helloWorldFunction, Proxy = false }); // Add a '/hello' resource with a GET method var helloResource = api.Root.AddResource("hello"); helloResource.AddMethod("GET"); } } }
Go

// ... import ( // ... // Import Api Gateway L2 construct "github.com/aws/aws-cdk-go/awscdk/v2/awsapigateway" // ... ) // ... func NewCdkHelloWorldStack(scope constructs.Construct, id string, props *CdkHelloWorldStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // Define the Lambda function resource // ... // Define the API Gatweay resource api := awsapigateway.NewLambdaRestApi(stack, jsii.String("HelloWorldApi"), &awsapigateway.LambdaRestApiProps{ Handler: helloWorldFunction, Proxy: jsii.Bool(false), }) // Add a '/hello' resource with a GET method helloResource := api.Root().AddResource(jsii.String("hello")) helloResource.AddMethod(jsii.String("GET")) return stack } // ...

您可以在此建立 API Gateway REST API 資源,以及下列項目:

  • REST API與您的 Lambda 函數之間的整合,可讓 API 叫用您的函數。這包括建立 Lambda 權限資源。

  • 名為的新資源或路徑hello,會新增至 API 端點的根目錄。這將創建一個新的端點,並添加/hello到您的基礎URL。

  • hello資源的 GET 方法。當 GET 要求傳送至/hello端點時,會叫用 Lambda 函數,並傳回其回應。

步驟 4:準備應用程式以進行部署

在此步驟中,您可以視需要建置並使用 AWS CDK CLIcdk synth命令執行基本驗證來準備應用程式以進行部署。

如有必要,建立您的應用程式:

TypeScript

從項目的根目錄中,運行以下命令:

$ npm run build
JavaScript

不需要建築物。

Python

不需要建築物。

Java

從項目的根目錄中,運行以下命令:

$ mvn package
C#

從項目的根目錄中,運行以下命令:

$ dotnet build src
Go

從項目的根目錄中,運行以下命令:

$ go build

運行cdk synth以從 CDK 代 AWS CloudFormation 碼合成模板。透過使用 L2 建構,許多組態詳細資料REST API都是為了促進 Lambda 函數之間的互動所需的,並由. AWS CloudFormation AWS CDK

從項目的根目錄中,運行以下命令:

$ cdk synth
注意

如果您收到類似下列的錯誤訊息,請確認您位於cdk-hello-world目錄中,然後再試一次:

--app is required either in command-line, in cdk.json or in ~/.cdk.json

如果成功, AWS CDK CLI將在命令提示符下以YAML格式輸出 AWS CloudFormation 模板。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 CLIcdk deploy命令來部署應用程式。該服務 AWS CDK 與 AWS CloudFormation 服務一起提供您的資源。

重要

在部署之前,您必須執行 AWS 環境的一次性啟動載入。如需指示,請參閱啟動您的環境

從項目的根目錄,運行以下命令。出現提示時確認變更:

$ 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.HelloWorldApiEndpointunique-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路徑。然後,使用瀏覽器或命令提示符,向端點發送 GET 請求。以下是範例:

$ curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/hello {"message":"Hello World!"}%

恭喜您,您已成功建立、部署您的應用程式,並使用 AWS CDK!

步驟 7:刪除您的應用程式

在此步驟中,您可以使 AWS CDK CLI用從中刪除您的應用程式 AWS 雲端。

若要刪除您的應用程式,請執行cdk destroy。出現提示時,請確認刪除應用程式的要求:

$ cdk destroy Are you sure you want to delete: CdkHelloWorldStack (y/n)? y CdkHelloWorldStack: destroying... [1/1] ... ✅ CdkHelloWorldStack: destroyed

故障診斷

錯誤:{「訊息」:「內部伺服器錯誤」}%

呼叫已部署的 Lambda 函數時,您會收到此錯誤訊息。發生此錯誤的原因有多種。

進一步疑難排解

使用 AWS CLI 來叫用您的 Lambda 函數。

  1. 修改堆疊檔案以擷取已部署 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 // ...
  2. 再次部署您的應用程式。 AWS CDK CLI將輸出您部署的 Lambda 函數名稱的值:

    $ cdk deploy ✨ Synthesis time: 0.29s ... ✅ CdkHelloWorldStack ✨ Deployment time: 20.36s Outputs: ... CdkHelloWorldStack.HelloWorldFunctionName = CdkHelloWorldStack-HelloWorldFunctionunique-identifier ...
  3. 使 AWS CLI 用在中叫用 Lambda 函數, AWS 雲端 並將回應輸出至文字檔案:

    $ aws lambda invoke --function-name CdkHelloWorldStack-HelloWorldFunctionunique-identifier output.txt
  4. 檢查output.txt以查看結果。

可能的原因:API Gateway 資源在堆疊檔案中定義不正確。

如果output.txt顯示成功的 Lambda 函數回應,則問題可能出在於您如何定義 API Gateway REST API。會直接 AWS CLI 呼叫您的 Lambda,而不是透過您的端點呼叫。檢查您的代碼,以確保它與本教程匹配。然後,再次部署。

可能的原因:堆疊檔案中的 Lambda 資源定義不正確。

如果output.txt返回錯誤,則問題可能出在於您如何定義 Lambda 函數。檢查您的代碼,以確保它與本教程匹配。然後再次部署。