Running a C++ AWS Lambda Function Locally with SAM: Step-by-Step Guide

The AWS SAM CLI and AWS CLI, along with Serverless and Localstack, can be used to test your AWS applications locally using the Serverless Framework and Localstack. It is essential for your IDE to work with AWS services. The AWS CLI allows you to use real credentials as described here, or you can use dummy ones.


Question:

I am interested in experimenting with the custom C++ runtime for
AWS Lambda
and testing it on my local machine using SAM. Regrettably, I encounter the following error

Runtime exited without providing a reason

(refer to the error details provided).
Can someone guide me on how to execute C++ Lambda functions locally using SAM?


Approach:

I am following the steps outlined in the official C++ Introduction blog, adhering to each instruction until the final step of “Creating your C++ function”. The remaining content of the blog focuses on deploying the function on Lambda, which is not my intention as I prefer to utilize SAM locally.

To utilize SAM, I am placing a

template.yaml

in the build directory. The configuration of the

build dir

appears as follows now:

├── CMakeCache.txt
├── CMakeFiles
|   |...
├── cmake_install.cmake
├── hello
├── hello.zip
├── Makefile
└── template.yaml
6 directories, 37 files

The build directory contains the content of

template.yaml

.

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
  cpp hello world
Globals: # default settings across all resources if nothing else is specified
  Function:
    Timeout: 15
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello.zip # relative location or S3 key
      Handler: hello # function to handle call? Why is this hello and not main?
      Runtime: provided
      Events:
        HelloWorld: # the name of the event
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get
Outputs:
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn


Invoke:

Currently, I am executing the

sam local start-api --debug

command within the

debug

directory. To activate the function, I access

127.0.0.1:3000/hello

using the Chrome browser.


Error:

Certain information extracted from the message generated by calling the URL:

...
Invoking hello (provided)
Decompressing /home/path/to/folder/test_cpp_local/aws-lambda-cpp/build/hello_cpp/build/hello.zip
Fetching lambci/lambda:provided Docker container image......
Mounting /tmp/tmpm9djt4mb as /var/task:ro,delegated inside runtime container
/var/task/bin/hello: error while loading shared libraries: /var/task/lib/libc.so.6: file too short
START RequestId: 3435a342-d86d-1a59-df1a-10167070cd22 Version: $LATEST
END RequestId: 3435a342-d86d-1a59-df1a-10167070cd22
REPORT RequestId: 3435a342-d86d-1a59-df1a-10167070cd22  Init Duration: 29.71 ms Duration: 0.00 ms   Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 6 MB   
{
  "errorType": "Runtime.ExitError",
  "errorMessage": "RequestId: 3435a342-d86d-1a59-df1a-10167070cd22 Error: Runtime exited without providing a reason"
}
Function returned an invalid response (must include one of: body, headers, multiValueHeaders or statusCode in the response object
...


My System:

I am utilizing cmake 3.5.1, g++ 4.5.0, and gcc 4.5.0 on Ubuntu 16.04 for my development purposes.

Some suggestions on how to address this issue are:

I need to construct a remote on a machine running AWS Linux (hopefully that’s not the situation).

Instead of utilizing the CloudFormationPackage as suggested on stackoverflow, I prefer to solely conduct local testing, thus avoiding its use.


Solution 1:

There is a high probability that the issue lies within this portion of code:

/var/task/bin/hello: error while loading shared libraries: /var/task/lib/libc.so.6: file too short

.

Your binary does not even invoke.

To resolve this issue, you can either create the binary using a corresponding version of

AWS Linux

or opt for building a static binary.


Solution 2:


Execute within a docker container.

It seems that the problem lies with SAM. I managed to achieve this by utilizing docker-lambda, where I had to extract

hello.zip

and subsequently invoke it.

docker run --rm -v "":/var/task lambci/lambda:provided handler

By employing this solution, there was no requirement for me to construct in a static manner.

Construct within a Docker container.

In addition to that, it is possible to construct within an amazonlinux container. A Dockerfile, which includes the program itself, would have the following appearance:

hello_world

.

FROM amazonlinux:latest
RUN yum -y install make
RUN yum -y install git
RUN yum -y install gcc-c++
RUN yum -y install nano
RUN yum -y install zip
RUN yum -y install clang
RUN yum -y install gcc-c++
RUN yum -y install libcurl-devel
RUN yum -y install cmake3
RUN export CC=gcc &&
export CXX=g++ &&
cd ~ &&
git clone https://github.com/awslabs/aws-lambda-cpp.git &&
cd aws-lambda-cpp &&
mkdir build &&
cd build &&
cmake3 .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=~/out &&
make &&
make install &&
mkdir hello-cpp-world &&
cd hello-cpp-world &&
echo -e "// main.cppn#include nusing namespace aws::lambda_runtime;ninvocation_response my_handler(invocation_request const& request)n{n return invocation_response::success("Hello

Frequently Asked Questions

Posted in Uncategorized