Deploy your C++ Lambda with Docker
So this blog is about How You Can Use Your C++ Runtime In Your Lambda Function. AWS Lambda allows us to use our app with serverless architecture. As an addition to all the available runtimes in AWS Lambda, AWS announced Custom Runtimes at Re:Invent 2018. They released open-source custom runtimes for C++.
The advantage of using a custom runtime is that it allows you to use any sort of code in your lambda function. AWS has previously given some examples to use C++ Api Runtime but there is not enough evidence on HOW to use a handler function and send and receive json data which I am going to explain now.
Prerequisites
You need a Linux-based environment. It will use for complying and deploying your code
##C++11 compiler, either GCC 5.x or later Clang 3.3 or later
$ yum install gcc64-c++ libcurl-devel
$ export CC=gcc64
$ export CXX=g++64##CMake v.3.5 or later.
$ yum install cmake3##Git
$ yum install git
Here, I will install all these tools with docker. So I only need to run my docker build command with my dockerfile than it installs all necessary Linux environment, complying C++ code and deploy to the AWS Lambda. It is using base AWS linux machine image.
##Warning1: This dockerfile is only using for your existed lambda update, please first create your lambda with aws-cli tool or from aws console.##Warning2: Please also create your api gateway which I am going to show you how to create and bind it to your C++ lambda as well.
The reason for using docker is that it will create an isolated place to work preventing all possible errors and make it simple and re-use.
C++ Lambda Compiler With Dockerfile
Open a project directory which includes your all project codes and also have your dockerfile there. Than we are going to create our docker image in this directory. So you need to change below command according to your project name and path. This is an example how it should look like:
Lets start to build our docker from dockerfile. First you need an base image which we will use amazonlinux base image.
FROM amazonlinux:latest
## install required development packages
RUN yum -y groupinstall "Development tools"
RUN yum -y install gcc-c++ libcurl-devel cmake3 git
RUN pip3 install awscli
This will use Amazon Linux for base image and install necessary tools.
And after we will add c++ API runtime environment. This will let you install and use lambda libraries for c++ in your code. You need to call handler function and it will use basically this c++ dependencies.
# install C++ runtime environment
RUN git clone https://github.com/awslabs/aws-lambda-cpp.git && \
cd aws-lambda-cpp && mkdir build && cd /aws-lambda-cpp/build && \
cmake3 .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF \
-DCMAKE_INSTALL_PREFIX=/out -DCMAKE_CXX_COMPILER=g++ && \
make && make install
This will install lambda c++ environment. You do not need to change anything in this part.
CMAKE will handle and use this library and make an output point which our main code using as a dependency in its code during complying.
# include C++ source code and build configuration
ADD adaptiveUpdate.cpp /adaptiveUpdate
ADD CMakeLists.txt /adaptiveUpdate
Copy your main code and CMAKE file to the docker container. Docker will use and copy when during creating image.
# compile & package C++ code
RUN cd /adaptiveUpdate && mkdir build && cd build && \
cmake3 .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF \
-DCMAKE_PREFIX_PATH=/out -DCMAKE_CXX_COMPILER=g++ && \
make && make aws-lambda-package-adaptiveUpdate
This will compile of our code and make a deployable zip file. You can change your package name what you desire and you will find it in it is your build folder which located under your code directory. Next step we are going to deploy this zip file as a lambda function to your AWS account with specific user and region. To make this happen we need to add ‘ENV’ which describe our user access id and secret key and configure region of AWS.
ENV AWS_DEFAULT_REGION=''
ENV AWS_ACCESS_KEY_ID=''
ENV AWS_SECRET_ACCESS_KEY=''
RUN aws lambda update-function-code --function-name hello-world \
--zip-file fileb://adaptiveUpdate/build/adaptiveUpdate.zip
Please add your secret key, access id and region to access and deploy your code to AWS. But firstly you need create a hello-world name lambda. It is another topic and you can find in this link:
Handler Method For Lambda
When you start using lambda, you will find the lambda function needs handler function and I am going to show you how you can import c++ handler function to your main code and how you retrieve your function as a return. Handler function is used to access lambda function and to send and retrieve JSON data.
Firstly you need to create a main function and it will call handler function. It is better to organize your code to take simple in main function. Than my handler function will call and
update itself by using other methods which take all processed about what app is doing.
int main()
{
run_handler(my_handler);
return 0;
}
That’s it! You only need to declare your handler function in your main than we are going to add other parts. Second part we will add to our code handler function which includes response and request when you invoke to lambda.
invocation_response my_handler(invocation_request const& req)
{
string json = req.payload;
test(json);
return invocation_response::success(json, "application/json");
}
In below part it directly receive payload of received JSON value. It separated from header. It only takes what you are sending.
string json = req.payload;
JSON value similar like this:
Than below line create a string variable and take ‘req.payload’ JSON value as a string and I will use it and update with my test function.
test(json);string json = req.payload;
Than I will return with it to main function with this updated value. This will return it as JSON format.
return invocation_response::success(json, "application/json");
Now we are going to move next stage how we can invoke lambda with apigateway
Apigateway For Invoke Lambda
There are several ways to invoke your lambda function(cli,s3 or apigateway) and today we are going to use apigateway REST API methods. You can also configure this gateway by swagger yaml which you can find it below this blow page.
We are going to use our apigateway as a proxy for this project. I will create a stage, resources and method. I will choose any method so it will behave as a proxy. Than we are going to integrate it with our lambda function.
1- First give a name to your REST API:
I give ‘cppjsonupdate’. Left everything is default and Create API with pushing right blue button.
2- Now we are going to create a new resources for our API. Choose create resources in actions menu and give name for your resources.
I am going to give my api and leave all other thing as default and click button at right corner.
3-And please add your method from actions menu. I will choose for ‘ANY’ but you can choose any of method. When you choose don’t forget to click green tick to save.
4-And now you can deploy your API from action menu with clicking deploy API. And choose popup menu stage. You need to add also ARN of Lambda function which you can find in Lambda service page. It is similar
arn:aws:lambda:us-east-1:34728394278492:function:adaptiveupdate
And choose new stage and give name. Then click to blue deploy button at right.
5- And that’s it you configure apigateway and integrate it to your c++ lambda. You can use endpoint for invocation. This is your final configuration. It should seen similar.
And finally you can find your invoke URL within stage section.
Conclusion
Hopefully you can now understand and use your code in lambda runtime API and you can easy manage create and deploy your function with docker. For test you can use postman as well.