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

使用 AWS CDK 部署 Lambda 函数

AWS Cloud Development Kit (AWS CDK) 是一个基础设施即代码(IaC)框架,可以让您使用所选编程语言来定义 AWS 云基础设施。要定义您自己的云基础设施,请首先编写一个包含一个或多个堆栈的应用程序(使用 CDK 支持的一种语言)。然后,将其合成为 AWS CloudFormation 模板并将您的资源部署到 AWS 账户。按照本主题中的步骤部署可从 Amazon API Gateway 端点返回事件的 Lambda 函数。

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 应用程序中的一个 AWS CloudFormation 堆栈。

要定义您的 CDK 堆栈,请按照首选编程语言的说明操作。此堆栈定义以下内容:

  • 函数的逻辑名称:MyFunction

  • code 属性中指定的函数代码的位置。有关更多信息,请参阅《AWS Cloud Development Kit (AWS CDK) API Reference》中的 Handler code

  • REST API 的逻辑名称:HelloApi

  • API Gateway 端点的逻辑名称:ApiGwEndpoint

请注意,本教程中的所有 CDK 堆栈都将 Node.js 运行时用于 Lambda 函数。可以为 CDK 堆栈和 Lambda 函数使用不同的编程语言,以利用每种语言的优势。例如,可以将 TypeScript 用于 CDK 堆栈,以利用静态输入为基础设施代码带来的好处。可以将 JavaScript 用于 Lambda 函数,以利用动态输入语言的灵活性和快速开发优势。

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.asset('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
    例 AWS 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: nodejs20.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