goaws-lambdamakefileaws-cdk

AWS Lambda with Go: "Runtime.InvalidEntrypoint" Error for POST Request to API Gateway Endpoint


I'm building an AWS Lambda function in Go that should be triggered via an API Gateway endpoint. I'm facing an issue where invoking the endpoint through a POST request results in a 502 error. I've set up my project based on a YouTube tutorial, but something seems to be off.

To compile my Go functions programmatically, I'm using a Makefile to generate a main executable in each function's directory. Here's the build section of my Makefile:

build:
    @echo "Building functions..."
    @$(foreach func, $(FUNCTIONS), \
        go build -o $(FUNCTIONS_DIR)/$(func)/$(BINARY_NAME) $(FUNCTIONS_DIR)/$(func)/main.go && \
        echo "Built $(func)/$(BINARY_NAME)"; \
    )

# Deploy stack with AWS CDK
.PHONY: deploy
deploy:
    echo "Deploying stack..."
    cdk deploy --profile $(AWS_PROFILE)

I deploy my stack with the command make deploy.

The relevant part of my love-go-serverless-stack.ts file looks like this:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { RestApi, LambdaIntegration } from 'aws-cdk-lib/aws-apigateway';

export class LoveGoServerlessStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Hello Lambda function
    const helloFunction = new lambda.Function(this, 'HelloFunction', {
      code: lambda.Code.fromAsset('src/functions/hello'),
      handler: 'main',
      runtime: lambda.Runtime.PROVIDED_AL2023,
    });

    // The API Gateway
    const gateway = new RestApi(this, 'MyGateway', {
      defaultCorsPreflightOptions: {
        allowOrigins: ['*'],
        allowMethods: ['GET', 'POST'],
      },
    });

    // The Lambda integration
    const integration = new LambdaIntegration(helloFunction);

    // Creating the '/hello' resource
    const helloResource = gateway.root.addResource('hello');
    helloResource.addMethod('POST', integration); // POST method for the 'hello' resource
  }
}

When I make a POST request to the CloudFront URL provided by API Gateway, I receive a 502 error. The CloudWatch logs indicate a recurring error related to the Lambda function's entry point:

RequestId: xxxxxxx-xxxx-xxxx-xxxx-xxxxxxx Error: Couldn't find valid bootstrap(s): [/var/task/bootstrap /opt/bootstrap]
Runtime.InvalidEntrypoint

And:

INIT_REPORT Init Duration: 0.27 ms Phase: invoke Status: error Error Type: Runtime.InvalidEntrypoint

I'm puzzled by the "invalid entrypoint" error, as I have configured the /hello route in my CDK stack (love-go-serverless-stack.ts). Could this be related to how the Go binary is named or packaged? Any insights or suggestions on what might be causing this and how to resolve it would be greatly appreciated.

The repository for the code

My environment:

enter image description here


Update


Solution

  • According to this Blog Post, migrating your Lambda function from the GO_1_X environment to the PROVIDED_AL2023 environment requires renaming the executable file to a generic bootstrap name. This modification necessitates changes to your build script. Additionally, I compressed the binary into a ZIP file to create a deployment package, making it ready for Lambda deployment.

    build:
      @echo "Building functions..."
      @$(foreach func, $(FUNCTIONS), \
          go build -o $(FUNCTIONS_DIR)/$(func)/bootstrap $(FUNCTIONS_DIR)/$(func)/main.go && \
          cd $(FUNCTIONS_DIR)/$(func); zip ../$(func).zip bootstrap \
          echo "Built $(func)/$(BINARY_NAME)"; \
      )
    
    # Deploy stack with AWS CDK
    .PHONY: deploy
    deploy:
        echo "Deploying stack..."
        cdk deploy --profile $(AWS_PROFILE)
    

    This will create zip packages in the $(FUNCTIONS_DIR) folder, allowing you to modify how you create a lambda function in your CDK project. Note that the handler must be renamed to bootstrap.

    const helloFunction = new lambda.Function(this, 'HelloFunction', {
        code: lambda.Code.fromAsset(path.join(__dirname, `../../bin/${func}.zip`)),,
        handler: 'bootstrap',
        runtime: lambda.Runtime.PROVIDED_AL2023,
    });