如何 运行 AWS Lambda dotnet on localstack
How to run AWS Lambda dotnet on localstack
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 存储桶(例如:my-bucket)
并将其部署到在自定义配置文件 myawsprofile
下配置的“真实”AWS
LocalStack 运行宁作为docker容器
到目前为止一切都很好。现在我刚刚发现 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 本地
为了 运行 AWS CLI 和 LocalStack,我安装了包装器 https://github.com/localstack/awscli-local 这样我就可以做一些事情
awslocal s3 ls
如何在本地部署 AWS Lambda?
我太新了,无法理解我所遵循的大部分教程。其中一些提到了无服务器框架,但我只是将 localstack 用作 docker 容器。我还安装了 SAM CLI 以备不时之需(虽然我还不明白它的用途)
我试过使用
将它部署到本地堆栈
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 in localstack
根据我的基本 AWS 知识水平,要找到一个我可以遵循的示例真的很复杂。 是否有任何我遗漏的说明,或者关于如何逐步实现我想要的目标的好方法link/tutorial?谢谢
更新 1 (11/3/2021)
我已逐步尝试使用使用亚马逊模板 https://gitlab.com/sunnyatticsoftware/sandbox/localstack-sandbox/-/tree/master/02-lambda-dotnet-webapi
创建的 Web api 项目
但我发现了问题。
步骤:
首先,我为 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
它returns:
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
有趣的是,我已经针对 REAL 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
它returns
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
我让它同时适用于 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 是类似的,但用 awslocal
替换 aws
,当然,我没有指定任何配置文件,但您可以使用 --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
在 localstack 中调用 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
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 存储桶(例如:my-bucket)
并将其部署到在自定义配置文件 myawsprofile
LocalStack 运行宁作为docker容器
到目前为止一切都很好。现在我刚刚发现 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 本地
为了 运行 AWS CLI 和 LocalStack,我安装了包装器 https://github.com/localstack/awscli-local 这样我就可以做一些事情
awslocal s3 ls
如何在本地部署 AWS Lambda?
我太新了,无法理解我所遵循的大部分教程。其中一些提到了无服务器框架,但我只是将 localstack 用作 docker 容器。我还安装了 SAM CLI 以备不时之需(虽然我还不明白它的用途)
我试过使用
将它部署到本地堆栈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 in localstack
根据我的基本 AWS 知识水平,要找到一个我可以遵循的示例真的很复杂。 是否有任何我遗漏的说明,或者关于如何逐步实现我想要的目标的好方法link/tutorial?谢谢
更新 1 (11/3/2021) 我已逐步尝试使用使用亚马逊模板 https://gitlab.com/sunnyatticsoftware/sandbox/localstack-sandbox/-/tree/master/02-lambda-dotnet-webapi
创建的 Web api 项目但我发现了问题。
步骤: 首先,我为 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
它returns:
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 有趣的是,我已经针对 REAL 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
它returns
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
我让它同时适用于 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 是类似的,但用 awslocal
替换 aws
,当然,我没有指定任何配置文件,但您可以使用 --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
在 localstack 中调用 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