如何在本地运行AWS Lambda的dotnet代码?

11

DotNet3.1 AWS Lambda

我使用Amazon模板创建了一个使用C# DotNet3.1的AWS Lambda解决方案。

dotnet new serverless.AspNetCoreWebAPI -n MyDotNet.Lambda.Service

这将创建一个Lambda函数,其处理程序为MyDotNet.Lambda.Service::MyDotNet.Lambda.Service.LambdaEntryPoint::FunctionHandlerAsync,还需要一些serverless.template文件和aws-lambda-tools-defaults.json

部署DotNet3.1 AWS Lambda的标准方式

部署的标准方式是安装Amazon.Lambda.Tools

dotnet tool update -g Amazon.Lambda.Tools

然后运行

dotnet lambda deploy-serverless --profile myawsprofile

注意,配置文件是可选的,但我已经在该配置文件下配置了AWS。 这会提示输入CloudFormation堆栈名称(例如:foo)和S3 Bucket(例如:my-bucket),并将其部署到使用自定义配置文件myawsprofile的"真实" AWS。

作为Docker容器运行的LocalStack

到目前为止一切都很好。现在我刚刚发现了https://github.com/localstack/localstack,它是在本地运行AWS平台的好方法,所以我使用docker-compose文件localstack-compose.yml来启动容器。

version: '3.8'

services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
    image: localstack/localstack-full
    network_mode: bridge
    ports:
      - "4566:4566"
      - "4571:4571"
      - "${PORT_WEB_UI-8080}:${PORT_WEB_UI-8080}"
    environment:
      - SERVICES=${SERVICES- }
      - DEBUG=${DEBUG- }
      - DATA_DIR=${DATA_DIR- }
      - PORT_WEB_UI=${PORT_WEB_UI- }
      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR- }
      - KINESIS_ERROR_PROBABILITY=${KINESIS_ERROR_PROBABILITY- }
      - DOCKER_HOST=unix:///var/run/docker.sock
      - HOST_TMP_FOLDER=${TMPDIR}
    volumes:
      - "${TMPDIR:-/tmp/localstack}:/tmp/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"

像这样:
docker-compose -f localstack-compose.yml up

它运行在4566端口下

AWS本地模拟器

为了使用LocalStack运行AWS CLI,我安装了包装器https://github.com/localstack/awscli-local,这样我就可以进行一些操作,比如

awslocal s3 ls

如何在本地部署 AWS Lambda?

我太新手了,无法理解我已经跟随的大多数教程。其中一些参考了 Serverless 框架,但我只是使用作为 Docker 容器的 LocalStack。我还安装了 SAM CLI(虽然我还不知道它的作用)。

我尝试使用以下方式将其部署到 LocalStack:

dotnet lambda deploy-serverless --profile default

我认为这应该是等效的,但我无法实现。

Error uploading to MyDotNet.Lambda.Service/AspNetCoreFunction-CodeUri-Or-ImageUri-637509113851513062-637509113886357582.zip in bucket foo: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint

尽管我在本地栈中有一个存储桶s3://foo,但要找到一个符合我的基本AWS知识水平的示例,实际上非常复杂。是否有任何我错过的说明或如何逐步实现我想要的漂亮链接/教程?谢谢。 更新1(11/3/2021) 我尝试了使用Amazon模板创建的Web API项目进行逐步操作。 https://gitlab.com/sunnyatticsoftware/sandbox/localstack-sandbox/-/tree/master/02-lambda-dotnet-webapi 但是我遇到了问题。
步骤: 首先为Lambda执行创建角色。
awslocal iam create-role --role-name lambda-dotnet-webapi-ex --assume-role-policy-document file://trust-policy.json

将策略附加到角色上以授予权限以进行执行。

awslocal iam attach-role-policy --role-name lambda-dotnet-webapi-ex --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

创建 Lambda 函数
awslocal lambda create-function --function-name lambda-dotnet-webapi-function --zip-file fileb://function.zip --handler Sample.Lambda.DotNet.WebApi::Sample.Lambda.DotNet.WebApi.LambdaEntryPoint::FunctionHandlerAsync --runtime dotnetcore3.1 --role arn:aws:iam::000000000000:role/lambda-dotnet-webapi-ex

使用base64工具解码日志并调用AWS Lambda

awslocal lambda invoke --function-name lambda-dotnet-webapi-function out --log-type Tail --query 'LogResult' --output text | base64 -d

它返回:
iptables v1.4.21: can't initialize iptables table `nat': iptables who? (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
[Information] Microsoft.Hosting.Lifetime: Application started. Press Ctrl+C to shut down.
[Information] Microsoft.Hosting.Lifetime: Hosting environment: Production
[Information] Microsoft.Hosting.Lifetime: Content root path: /var/task
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /var/task
START RequestId: a5eb1d2d-d908-15f6-ace3-d4d0e01a0066 Version: $LATEST
Could not load file or assembly 'System.IO.Pipelines, Version=4.0.2.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
: FileNotFoundException
   at Amazon.Lambda.AspNetCoreServer.AbstractAspNetCoreFunction`2.FunctionHandlerAsync(TREQUEST request, ILambdaContext lambdaContext)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Amazon.Lambda.AspNetCoreServer.AbstractAspNetCoreFunction`2.FunctionHandlerAsync(TREQUEST request, ILambdaContext lambdaContext)
   at lambda_method(Closure , Stream , Stream , LambdaContextInternal )


END RequestId: a5eb1d2d-d908-15f6-ace3-d4d0e01a0066
REPORT RequestId: a5eb1d2d-d908-15f6-ace3-d4d0e01a0066  Init Duration: 2305.87 ms       Duration: 33.29 ms      Billed Duration: 100 ms      Memory Size: 1536 MB    Max Memory Used: 0 MB
Starting daemons...
ImportError: No module named site

有人有可行的示例吗?

更新2 有趣的是,我已经尝试了在真正的AWS(使用不同的AWS凭据配置文件)中进行测试,我仍然会收到错误消息,但是这次错误不同。

创建角色

aws iam create-role --role-name lambda-dotnet-webapi-ex --assume-role-policy-document file://trust-policy.json --profile diegosasw

列出角色

aws iam list-roles --profile diegosasw

附加策略

aws iam attach-role-policy --role-name lambda-dotnet-webapi-ex
 --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole --profile diegosasw

创建 lambda
aws lambda create-function --function-name lambda-dotnet-webap
i-function --zip-file fileb://function.zip --handler Sample.Lambda.DotNet.WebApi::Sample.Lambda.DotNet.WebApi.LambdaEntryPoint::FunctionHa
ndlerAsync --runtime dotnetcore3.1 --role arn:aws:iam::308309238958:role/lambda-dotnet-webapi-ex --profile diegosasw

调用

aws lambda invoke --function-name lambda-dotnet-webapi-function --profile diegosasw out --log-type Tail --query 'LogResult' --output text | base64 -d

它返回

START RequestId: 7d77489f-869b-4e4d-87a0-ac800d71eb2d Version: $LATEST
warn: Amazon.Lambda.AspNetCoreServer.AbstractAspNetCoreFunction[0]
      Request does not contain domain name information but is derived from APIGatewayProxyFunction.
[Warning] Amazon.Lambda.AspNetCoreServer.AbstractAspNetCoreFunction: Request does not contain domain name information but is derived from APIGatewayProxyFunction.
Object reference not set to an instance of an object.: NullReferenceException
   at Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction.MarshallRequest(InvokeFeatures features, APIGatewayProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
   at Amazon.Lambda.AspNetCoreServer.AbstractAspNetCoreFunction`2.FunctionHandlerAsync(TREQUEST request, ILambdaContext lambdaContext)
   at lambda_method(Closure , Stream , Stream , LambdaContextInternal )


END RequestId: 7d77489f-869b-4e4d-87a0-ac800d71eb2d
REPORT RequestId: 7d77489f-869b-4e4d-87a0-ac800d71eb2d  Duration: 755.06 ms     Billed Duration: 756 ms Memory Size: 128 MB     Max Memory Used: 87 MB    Init Duration: 462.09 ms
1个回答

11

我已经成功地在AWS和LocalStack(即awslocal)中都实现了它。以下是只使用AWS CLI的步骤。这里有一个示例存储库https://gitlab.com/sunnyatticsoftware/sandbox/localstack-sandbox/-/tree/master/03-lambda-dotnet-empty

使用AWS CLI在Localstack中创建AWS Lambda

AWS

从Amazon模板中创建空的C# Lambda函数示例。

dotnet new lambda.EmptyFunction -n Sample.Lambda.DotNet

编译并发布

dotnet build
dotnet publish -c Release -o publish

压缩Lambda文件

cd publish
zip -r ../function.zip *

创建角色
aws --profile diegosasw iam create-role --role-name lambda-dotnet-ex --assume-role-policy-document '{"Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'

将AWSLambdaBasicExecutionRole策略附加到角色

aws --profile diegosasw iam attach-role-policy --role-name lambda-dotnet-ex --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

创建lambda函数
aws --profile diegosasw lambda create-function --function-name lambda-dotnet-function --zip-file fileb://function.zip --handler Sample.Lambda.DotNet::Sample.Lambda.DotNet.Function::FunctionHandler --runtime dotnetcore3.1 --role arn:aws:iam::308309238958:role/lambda-dotnet-ex

调用 lambda 函数

aws --profile diegosasw lambda invoke --function-name lambda-dotnet-function --payload "\"Just Checking If Everything is OK\"" response.json --log-type Tail

LocalStack

LocalStack是一个类似的工具,但是将aws替换为awslocal,当然,我没有指定任何配置文件,但你可以使用--profile default或者放置在.aws/credentials中的任何凭证文件。

创建角色。

awslocal iam create-role --role-name lambda-dotnet-ex --assume-role-policy-document '{"Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'

将AWSLambdaBasicExecutionRole策略附加到角色

awslocal iam attach-role-policy --role-name lambda-dotnet-ex --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

创建Lambda函数

awslocal lambda create-function --function-name lambda-dotnet-function --zip-file fileb://function.zip --handler Sample.Lambda.DotNet::Sample.Lambda.DotNet.Function::FunctionHandler --runtime dotnetcore3.1 --role arn:aws:iam::000000000000:role/lambda-dotnet-ex

在本地堆栈中调用lambda并传递JSON有效负载(字符串是有效的JSON)。
awslocal lambda invoke --function-name lambda-dotnet-function --payload "\"Just Checking If Everything is OK again\"" response.json --log-type Tail

视图函数

awslocal lambda list-functions

删除功能

awslocal lambda delete-function --function-name lambda-dotnet-function

Dotnet 工具

使用 Dotnet 工具,相当于

dotnet lambda invoke-function lambda-dotnet-function --payload "Just Checking If Everything is OK" --profile diegosasw

dotnet lambda .... 在这里是最简单和最好的解决方案!也感谢其他的建议,但最后一个真是太棒了。 - Learning AWS and PostgreSQL
哦等等-我忘记提到@diegosasw.. donet lambda命令是否允许我们将其发布到localstack?感觉上好像只能将其发布到实际的AWS。 - Learning AWS and PostgreSQL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接