How to debug and run multiple lambdas locally
Asked Answered
D

2

6

I would like to build .NET HTTP API using aws lambdas. These lambdas will be called by UI and some other systems via api gateway. Obviously in local environment I would like to run/debug these.

What I have tried:

a) Using the mock tool that comes with AWS Visual Studio templates. You can call individual lambdas but I couldn't figure out how I can call them from e.g. postman using normal rest calls. I don't know how mock tool makes those calls as chrome/firefox doesn't show them.

b) Using sam local start-api. Here is what I did:

sam --version
SAM CLI, version 1.22.0
sam init (choose aws quick start template, package type Image and amazon/dotnet5.0-base as base image)

I can build the solution with sam build, run it wit sam local start-api and I can browse to http://localhost:3000/hello and it works. Problem is that I would need to do build in VS + do those steps every time I change code. Also no easy way to attach debugger.

So what is the recommended way to do this? I know you can run whole .NET web api inside lambda but that doesn't sound like a good technical solution. I am assuming I am not the first person building HTTP api using lambdas.

Dip answered 18/4, 2021 at 8:10 Comment(0)
B
2

You can use sam local

Create API with API gateway example

                Resources:
                  ApiGatewayToLambdaRole:
                    Type: AWS::IAM::Role
                    Properties:
                      AssumeRolePolicyDocument:
                        Statement:
                          - Action: ['sts:AssumeRole']
                            Effect: Allow
                            Principal:
                              Service: ['apigateway.amazonaws.com']
                        Version: '2012-10-17'
                      ManagedPolicyArns:
                        - arn:aws:iam::aws:policy/service-role/AWSLambdaRole
                        - arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs

                  ApiGateway:
                    Type: AWS::Serverless::Api
                    Properties:
                      StageName: test
                      EndpointConfiguration: REGIONAL
                      DefinitionBody:
                        swagger: "2.0"
                        info:
                          title: "TestAPI"
                          description: TestAPI description in Markdown.
                        paths:
                          /create:
                            post:
                              x-amazon-apigateway-integration:
                                uri:
                                  !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambda.Arn}/invocations
                                credentials: !GetAtt ApiGatewayToLambdaRole.Arn
                                responses: {}
                                httpMethod: POST
                                type: aws
                        x-amazon-apigateway-request-validators:
                          Validate query string parameters and headers:
                            validateRequestParameters: true
                            validateRequestBody: false

                  LambdaRole:
                    Type: AWS::IAM::Role
                    Properties:
                      AssumeRolePolicyDocument:
                        Statement:
                          - Action: ['sts:AssumeRole']
                            Effect: Allow
                            Principal:
                              Service: [lambda.amazonaws.com]
                        Version: '2012-10-17'
                      Path: /
                      Policies:
                        - PolicyName: CodeBuildAccess
                          PolicyDocument:
                            Version: '2012-10-17'
                            Statement:
                            - Action:
                              - logs:*
                              - lambda:*
                              - ec2:CreateNetworkInterface
                              - ec2:DescribeNetworkInterfaces
                              - ec2:DeleteNetworkInterface
                              Effect: Allow
                              Resource: "*"
                            Version: '2012-10-17'

                  MyLambda:
                    Type: AWS::Serverless::Function
                    Properties:
                      Role: !GetAtt LambdaRole.Arn
                      Handler: myfunctionname.lambda_handler
                      CodeUri: ./src/myfunctionname
                      Events:
                        SCAPIGateway:
                          Type: Api
                          Properties:
                            RestApiId: !Ref ApiGateway
                            Path: /create
                            Method: POST
                ...

Build :

Time sam build --use-container --template backend/template.yam

Invoke Lambda Locally:

The command to invoke Lambda locally is sam local invoke and -e flag is used to specify the path to the Lambda event.

        $ sam local invoke -e event.json

When it is run, it will look something like this:

     $ sam local invoke MyLambda -e event.json

   2021-04-20 11:11:09 Invoking index.handler 
   2021-04-20 11:11:09 Found credentials in shared credentials file: 
   ~/.aws/credentials
Boatel answered 20/4, 2021 at 14:58 Comment(2)
As I wrote, with sam local I setup local api gateway and call apis but at least with .NET 5 you need to run sam build which builds the container and installs my lambda there. Every time I change my code, I need to run sam build again. This is very slow feedback loop when I want to change something and test it. Also I didn't find information how I can attach my debugger (g.e. from Visual Studio) to the running code.Dip
I never used .net,may be following link help #47402544Boatel
H
1

It might be worth considering running a lambda-like environment in Docker.

While including the dotnet tools you need might not be feasable in actual Lambda, It might be feasible to either include them in a Docker image, or bind mounted to a docker container. These images from lambci can help with that: https://hub.docker.com/r/lambci/lambda/

Hyperbolic answered 20/4, 2021 at 14:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.