使用 AWS CDK 部署 Lambda 函式 - AWS Lambda

使用 AWS CDK 部署 Lambda 函式

AWS Cloud Development Kit (AWS CDK) 是基礎設施即程式碼 (IaC) 架構,可讓您使用您選擇的程式語言來定義 AWS 雲端基礎設施。若要定義您自己的雲端基礎設施,要先編寫包含一個或更多堆疊的應用程式 (使用 CDK 支援的其中一種語言)。然後將其合成為 CloudFormation 模板,並將您的資源部署至 AWS 帳戶。按照本主題中的步驟部署一個 Lambda 函數,從 Amazon API Gateway 端點傳回事件。

CDK 隨附的 AWS 建構程式庫提供模組,讓您可為 AWS 服務 服務所提供的資源建立模型。針對熱門服務,程式庫會提供具有智能預設和最佳實務的彙整建構。您可以使用 aws_lambda 模組來定義函數和相關資源,幾行程式碼即可完成。

必要條件

在開始本教學課程之前,請執行以下命令來安裝 AWS CDK。

npm install -g aws-cdk

步驟 1:設定您的 AWS CDK 專案

為您的新 AWS CDK 應用程式建立目錄並初始化專案。

JavaScript
mkdir hello-lambda cd hello-lambda cdk init --language javascript
TypeScript
mkdir hello-lambda cd hello-lambda cdk init --language typescript
Python
mkdir hello-lambda cd hello-lambda cdk init --language python

專案開始後,啟用專案的虛擬環境,並安裝 AWS CDK 的基準相依項。

source .venv/bin/activate python -m pip install -r requirements.txt
Java
mkdir hello-lambda cd hello-lambda cdk init --language java

將此 Maven 專案匯入 Java 整合式開發環境 (IDE)。例如,在 Eclipse 中,依次選擇檔案 > 匯入 > Maven > 現有的 Maven 專案

C#
mkdir hello-lambda cd hello-lambda cdk init --language csharp
注意

AWS CDK 應用程式範本使用專案目錄的名稱,以便為來源檔案和類別產生名稱。在此範例中,目錄名為 hello-lambda。若使用不同的專案目錄名稱,您的應用程式將與這些說明不相符。

AWS CDK v2 的單一套件 (稱為 aws-cdk-lib) 中包含適用於所有 AWS 服務 的穩定構建。在初始化專案時,此套件會安裝為相依性套件。使用某些程式設計語言時,套件會在您第一次建置專案時安裝。

步驟 2:刪除 AWS CDK 堆疊

CDK 堆疊是一或多個建構模組的集合,而建構模組定義 AWS 資源。每個 CDK 堆疊代表 CDK 應用程式中的一個 CloudFormation 堆疊。

若要定義 CDK 堆疊,請遵循您偏好之程式設計語言的指示。此堆疊定義下列項目:

  • 函數的邏輯名稱:MyFunction

  • 函數程式碼的位置 (在 code 屬性中指定)。如需詳細資訊,請參閱 AWS Cloud Development Kit (AWS CDK) API Reference 中的 Handler code 一節。

  • REST API 的邏輯名稱:HelloApi

  • API Gateway 端點的邏輯名稱:ApiGwEndpoint

請注意,本教學課程中的所有 CDK 堆疊都會使用 Lambda 函數的 Node.js 執行時期。您可以針對此 CDK 堆疊和 Lambda 函數使用不同的程式設計語言,以利用每種語言的優勢。例如,您可以針對 CDK 堆疊使用 TypeScript,以利用基礎設施程式碼靜態輸入的優勢。您可以針對 Lambda 函數使用 JavaScript,以利用動態類型語言的彈性和快速開發優勢。

JavaScript

開啟 lib/hello-lambda-stack.js 檔案並將內容替換如下:

const { Stack } = require('aws-cdk-lib'); const lambda = require('aws-cdk-lib/aws-lambda'); const apigw = require('aws-cdk-lib/aws-apigateway'); class HelloLambdaStack extends Stack { /** * * @param {Construct} scope * @param {string} id * @param {StackProps=} props */ constructor(scope, id, props) { super(scope, id, props); const fn = new lambda.Function(this, 'MyFunction', { code: lambda.Code.fromAsset('lib/lambda-handler'), runtime: lambda.Runtime.NODEJS_LATEST, handler: 'index.handler' }); const endpoint = new apigw.LambdaRestApi(this, 'MyEndpoint', { handler: fn, restApiName: "HelloApi" }); } } module.exports = { HelloLambdaStack }
TypeScript

開啟 lib/hello-lambda-stack.ts 檔案並將內容替換如下:

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as apigw from "aws-cdk-lib/aws-apigateway"; import * as lambda from "aws-cdk-lib/aws-lambda"; import * as path from 'node:path'; export class HelloLambdaStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps){ super(scope, id, props) const fn = new lambda.Function(this, 'MyFunction', { runtime: lambda.Runtime.NODEJS_LATEST, handler: 'index.handler', code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); const endpoint = new apigw.LambdaRestApi(this, `ApiGwEndpoint`, { handler: fn, restApiName: `HelloApi`, }); } }
Python

開啟 /hello-lambda/hello_lambda/hello_lambda_stack.py 檔案並將內容替換如下:

from aws_cdk import ( Stack, aws_apigateway as apigw, aws_lambda as _lambda ) from constructs import Construct class HelloLambdaStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) fn = _lambda.Function( self, "MyFunction", runtime=_lambda.Runtime.NODEJS_LATEST, handler="index.handler", code=_lambda.Code.from_asset("lib/lambda-handler") ) endpoint = apigw.LambdaRestApi( self, "ApiGwEndpoint", handler=fn, rest_api_name="HelloApi" )
Java

開啟 /hello-lambda/src/main/java/com/myorg/HelloLambdaStack.java 檔案並將內容替換如下:

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.apigateway.LambdaRestApi; import software.amazon.awscdk.services.lambda.Function; public class HelloLambdaStack extends Stack { public HelloLambdaStack(final Construct scope, final String id) { this(scope, id, null); } public HelloLambdaStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Function hello = Function.Builder.create(this, "MyFunction") .runtime(software.amazon.awscdk.services.lambda.Runtime.NODEJS_LATEST) .code(software.amazon.awscdk.services.lambda.Code.fromAsset("lib/lambda-handler")) .handler("index.handler") .build(); LambdaRestApi api = LambdaRestApi.Builder.create(this, "ApiGwEndpoint") .restApiName("HelloApi") .handler(hello) .build(); } }
C#

開啟 src/HelloLambda/HelloLambdaStack.cs 檔案並將內容替換如下:

using Amazon.CDK; using Amazon.CDK.AWS.APIGateway; using Amazon.CDK.AWS.Lambda; using Constructs; namespace HelloLambda { public class HelloLambdaStack : Stack { internal HelloLambdaStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { var fn = new Function(this, "MyFunction", new FunctionProps { Runtime = Runtime.NODEJS_LATEST, Code = Code.FromAsset("lib/lambda-handler"), Handler = "index.handler" }); var api = new LambdaRestApi(this, "ApiGwEndpoint", new LambdaRestApiProps { Handler = fn }); } } }

步驟 3:建立 Lambda 函數程式碼

  1. 從專案 (hello-lambda) 的根目錄建立 Lambda 函數程式碼的 /lib/lambda-handler 目錄。此目錄是在 AWS CDK 堆疊的 code 屬性中指定。

  2. /lib/lambda-handler 目錄中,建立名為 index.js 的新檔案。將以下程式碼貼到檔案。該函數會從 API 請求擷取特定屬性,並將其傳回為 JSON 回應。

    exports.handler = async (event) => { // Extract specific properties from the event object const { resource, path, httpMethod, headers, queryStringParameters, body } = event; const response = { resource, path, httpMethod, headers, queryStringParameters, body, }; return { body: JSON.stringify(response, null, 2), statusCode: 200, }; };

步驟 4:部署 AWS CDK 堆疊

  1. 從專案根目錄執行 cdk synth 命令:

    cdk synth

    此命令會從 CDK 堆疊合成 AWS CloudFormation 範本。該範本是大約為 400 行的 YAML 檔案,與下面的內容相似:

    注意

    如果您遇到以下錯誤,請確定您位於專案目錄的根目錄。

    --app is required either in command-line, in cdk.json or in ~/.cdk.json
    範例 CloudFormation 範本
    Resources: MyFunctionServiceRole3C357FF2: 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: HelloLambdaStack/MyFunction/ServiceRole/Resource MyFunction1BAA52E7: Type: AWS::Lambda::Function Properties: Code: S3Bucket: Fn::Sub: cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region} S3Key: ab1111111cd32708dc4b83e81a21c296d607ff2cdef00f1d7f48338782f92l3901.zip Handler: index.handler Role: Fn::GetAtt: - MyFunctionServiceRole3C357FF2 - Arn Runtime: nodejs22.x ...
  2. 執行 cdk deploy 命令:

    cdk deploy

    等待資源建立完畢。最終輸出包含 API Gateway 端點的 URL。範例:

    Outputs: HelloLambdaStack.ApiGwEndpoint77F417B1 = https://abcd1234.execute-api.us-east-1.amazonaws.com/prod/

步驟 5:測試函數

若要調用該 Lambda 函數,請複製 API Gateway 端點並將其貼到 Web 瀏覽器或執行 curl 命令:

curl -s https://abcd1234.execute-api.us-east-1.amazonaws.com/prod/

回應是從原始事件物件所選取屬性的 JSON 表示,其中包含對 API Gateway 端點提出之請求的相關資訊。範例:

{ "resource": "/", "path": "/", "httpMethod": "GET", "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Accept-Encoding": "gzip, deflate, br, zstd", "Accept-Language": "en-US,en;q=0.9", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-ASN": "16509", "CloudFront-Viewer-Country": "US", "Host": "abcd1234.execute-api.us-east-1.amazonaws.com", ...

步驟 6:清除您的資源

API Gateway 端點可公開存取。為了避免意外產生費用,請執行 cdk destroy 命令來刪除堆疊和所有相關聯的資源。

cdk destroy

後續步驟

如需有關以所選語言編寫 AWS CDK 應用程式的資訊,請參閱以下:

TypeScript

以 TypeScript 使用 AWS CDK

JavaScript

以 JavaScript 使用 AWS CDK

Python

以 Python 使用 AWS CDK

Java

以 Java 使用 AWS CDK

C#

以 C# 使用 AWS CDK

Go

以 Go 使用 AWS CDK