kbaldwinnexus
kbaldwinnexus

Reputation: 11

Amazon AWS C# Lambda Code Pipeline

Wrote a .NET core 2 web api application using the Amazon Lambda Function template. Wrote some test calls using postman. Everything works fine with .NET core code running locally. Uploaded .NET core code to Lambda function, modified postman to call that URL. Everything works fine with .NET code running inside Lambda function - calling locally using Postman.

The requirement now is to call the .NET core code inside a Lambda function - from aws codepipline. Cannot get this to work

When Postman calls the lambda function - I see this in cloudwatch logs:

Lambda Deserialize Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest:
{
    "resource": "/{proxy+}",
    "path": "/api/Rds/InstanceStatus",
    "httpMethod": "GET",

and this call works! My .NET core code logs the following

LOG_LEVEL_TRACE,Nexus.Rds.Restore.dll,1.0.0.0,Nexus.Rds.Restore.LambdaEntryPoint,FunctionHandlerAsync,APIGatewayProxyRequest.Body = null

LOG_LEVEL_TRACE,Nexus.Rds.Restore.dll,1.0.0.0,Nexus.Rds.Restore.LambdaEntryPoint,FunctionHandlerAsync,APIGatewayProxyRequest.HttpMethod = GET

LOG_LEVEL_TRACE,Nexus.Rds.Restore.dll,1.0.0.0,Nexus.Rds.Restore.LambdaEntryPoint,FunctionHandlerAsync,APIGatewayProxyRequest.Path = /api/Rds/InstanceStatus

LOG_LEVEL_TRACE,Nexus.Rds.Restore.dll,1.0.0.0,Nexus.Rds.Restore.LambdaEntryPoint,FunctionHandlerAsync,APIGatewayProxyRequest.Resource = /{proxy+}

Note - you can see that the LambdaEntryPoint object is being populated before calling my .NET core code

When I try to duplicate this same call from within codepipeline - I see this in the cloudwatch logs:

Lambda Deserialize Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest:
{
    "CodePipeline.job": {
        "id": "379d05fe-ec03-4ec9-8bce-59f31901aeb8",
        "accountId": "109319094079",
        "data": {
            "actionConfiguration": {
                "configuration": {
                    "FunctionName": "NexuIntRestServerless2-AspNetCoreFunction-T8Q5XCCN0FIC",
                    "UserParameters": "{\"resource\":\"/{proxy+}\",\"path\":\"/api/Rds/InstanceStatus\",\"httpMethod\":\"GET\"}"
                }
            },

I've tried to reproduce the parameters in codepipeline user parameters. However, my .NET core code logging looks like this:

LOG_LEVEL_TRACE,Nexus.Rds.Restore.dll,1.0.0.0,Nexus.Rds.Restore.LambdaEntryPoint,FunctionHandlerAsync,APIGatewayProxyRequest.Body = null

LOG_LEVEL_TRACE,Nexus.Rds.Restore.dll,1.0.0.0,Nexus.Rds.Restore.LambdaEntryPoint,FunctionHandlerAsync,APIGatewayProxyRequest.HttpMethod = null

LOG_LEVEL_TRACE,Nexus.Rds.Restore.dll,1.0.0.0,Nexus.Rds.Restore.LambdaEntryPoint,FunctionHandlerAsync,APIGatewayProxyRequest.Path = null

LOG_LEVEL_TRACE,Nexus.Rds.Restore.dll,1.0.0.0,Nexus.Rds.Restore.LambdaEntryPoint,FunctionHandlerAsync,APIGatewayProxyRequest.Resource = null

LOG_LEVEL_TRACE,Nexus.Rds.Restore.dll,1.0.0.0,Nexus.Rds.Restore.LambdaEntryPoint,FunctionHandlerAsync,APIGatewayProxyRequest.RequestContext = null

NOTE: the LambdaEntryPoint is now null, and an exception is thrown - I assume because .NET core does not know how to route the call:

One or more errors occurred. (Object reference not set to an instance of an object.): AggregateException
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at lambda_method(Closure , Stream , Stream , LambdaContextInternal )

at Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction.MarshallRequest(InvokeFeatures features, APIGatewayProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
at Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction.<FunctionHandlerAsync>d__13.MoveNext()

Any ideas on how to call the Lambda Function from within Codepipeline?

Thanks

Upvotes: 1

Views: 1263

Answers (1)

TimB
TimB

Reputation: 1567

It looks like you're using API gateway when you invoke the function via postman.

Calling from API gateway will have a different function inputs to when calling from CodePipeline, because the input from API gateway is representing a HTTP request vs. a CodePipeline job.

Your Lambda function needs to be designed to handle the input of a CodePipeline job.

There's documentation about the format of this job and how to consume it, then report the result back to CodePipeline here: https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html

Upvotes: 1

Related Questions