|
1 | | -## AWS Lambda Cpp Runtime |
| 1 | +## AWS Lambda C++ Runtime |
2 | 2 |
|
3 | 3 | C++ implementation of the lambda runtime API |
4 | 4 |
|
5 | | -## License |
| 5 | +## Building The Runtime |
| 6 | +Since AWS Lambda runs on GNU/Linux, you should build this runtime library and your logic on GNU/Linux as well. |
| 7 | + |
| 8 | + |
| 9 | +Using CMake, run the following commands: |
| 10 | +```cmake |
| 11 | +$ git clone https://github.com/awslabs/aws-lambda-cpp-runtime.git |
| 12 | +$ cd aws-lambda-cpp-runtime |
| 13 | +$ mkdir build |
| 14 | +$ cd build |
| 15 | +$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/lambda-install |
| 16 | +$ make && make install |
| 17 | +``` |
| 18 | + |
| 19 | +To consume this library in a project that is also using CMake, you would do: |
| 20 | + |
| 21 | +```cmake |
| 22 | +cmake_minimum_required(VERSION 3.5) |
| 23 | +set(CMAKE_CXX_STANDARD 11) |
| 24 | +project(demo LANGUAGES CXX) |
| 25 | +find_package(aws-lambda-runtime) |
| 26 | +add_executable(${PROJECT_NAME} "main.cpp") |
| 27 | +target_link_libraries(${PROJECT_NAME} PRIVATE AWS::aws-lambda-runtime) |
| 28 | +target_compile_features(${PROJECT_NAME} PRIVATE "cxx_std_11") |
| 29 | +target_compile_options(${PROJECT_NAME} PRIVATE "-Wall" "-Wextra") |
| 30 | +
|
| 31 | +# this line creates a target that packages your binary and zips it up |
| 32 | +aws_lambda_package_target(${PROJECT_NAME}) |
| 33 | +``` |
| 34 | + |
| 35 | +And here is how a sample `main.cpp` would look like for example: |
| 36 | +```cpp |
| 37 | +#include <aws/lambda-runtime/runtime.h> |
| 38 | + |
| 39 | +using namespace aws::lambda_runtime; |
| 40 | + |
| 41 | +static invocation_response my_handler(invocation_request const& req) |
| 42 | +{ |
| 43 | + if (req.payload.length() > 42) { |
| 44 | + return invocation_response::failure("error message here"/*error_message*/, "error type here" /*error_type*/); |
| 45 | + } |
| 46 | + |
| 47 | + return invocation_response::success("json payload here" /*payload*/, "application/json" /*MIME type*/); |
| 48 | +} |
| 49 | + |
| 50 | +int main() |
| 51 | +{ |
| 52 | + run_handler(my_handler); |
| 53 | + return 0; |
| 54 | +} |
| 55 | +``` |
| 56 | + |
| 57 | +And finally, here's how you would package it all and send it to AWS Lambda. Run the following commands |
| 58 | +from your application's root directory: |
| 59 | + |
| 60 | +```bash |
| 61 | +$ mkdir build |
| 62 | +$ cd build |
| 63 | +$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=~/lambda-install |
| 64 | +$ make |
| 65 | +$ make aws-lambda-package-demo |
| 66 | +``` |
| 67 | +The last command above `make aws-lambda-package-demo` will create a zip file called `demo.zip` in the current directory. |
| 68 | + |
| 69 | +Using the aws CLI, create a lambda function that uses that zip file as such: |
6 | 70 |
|
| 71 | +```bash |
| 72 | +$ aws lambda create-function --function-name demo \ |
| 73 | +--role <specify role arn here> \ |
| 74 | +--runtime provided --timeout 15 --memory-size 128 \ |
| 75 | +--handler demo --zip-file fileb://demo.zip |
| 76 | +``` |
| 77 | + |
| 78 | +And to invoke the function: |
| 79 | +```bash |
| 80 | +$ aws lambda invoke --function-name demo --payload '{"answer":42}' output.txt |
| 81 | +``` |
| 82 | + |
| 83 | +## Using the C++ SDK for AWS with this runtime |
| 84 | +This library is completely independent from the AWS C++ SDK. You should treat the AWS C++ SDK as just another dependency in your application. |
| 85 | +This is a [detailed example](https://github.com/awslabs/aws-lambda-cpp-runtime/examples/README.md) of using the AWS C++ SDK with this Lambda runtime. |
| 86 | + |
| 87 | +## Supported Compilers |
| 88 | +We've tested with Clang & GCC but in theory any *fully* compliant C++11 compiler targeting GNU/Linux x86-64 should work. |
| 89 | + |
| 90 | +## Packaging, ABI, GNU C Library, Oh My! |
| 91 | +Lambda runs your code on some version of Amazon Linux. It would be a less than ideal customer experience if you are forced to build your application on that platform and that platform only. |
| 92 | + |
| 93 | +However, the freedom to build on any linux distro brings a challenge. The GNU C Library ABI. There is no guarantee the platform used to build the Lambda function has the same GLIBC version as the one used by AWS Lambda. In fact, you might not even be using GNU's implementation. For example you could build a C++ Lambda function using musl libc. |
| 94 | + |
| 95 | +To ensure that your application will run correctly on Lambda, , we must package the entire C runtime library with your function. |
| 96 | +If you choose to build on the same Amazon Linux version used by lambda, you could avoid packaging the C runtime in your zip file. |
| 97 | +This can be done by passing the `NO_LIBC` flag in CMake as follows: |
| 98 | +```cmake |
| 99 | +aws_lambda_package_target(${PROJECT_NAME} NO_LIBC) |
| 100 | +``` |
| 101 | +### Common Pitfalls with Packaging |
| 102 | + |
| 103 | +* Any library dependency your Lambda function has that is dynamically loaded via `dlopen` will NOT be automatically packaged. You **must** add those dependencies manually to the zip file. |
| 104 | +This applies to any configuration or resource files that your code depends on. |
| 105 | + |
| 106 | +* If you are making HTTP calls over TLS (https), keep in mind that the CA bundle location is different between distros. |
| 107 | +For example, if you are using the AWS C++ SDK, it's best to set the following configuration options: |
| 108 | + |
| 109 | +```cpp |
| 110 | +Aws::Client::ClientConfiguration config; |
| 111 | +config.caFile = "/etc/pki/tls/certs/ca-bundle.crt"; |
| 112 | +``` |
| 113 | +If you are not using the AWS C++ SDK, but happens to be using libcurl directly, you can set the CA bundle location by doing: |
| 114 | +```c |
| 115 | +curl_easy_setopt(curl_handle, CURLOPT_CAINFO, "/etc/pki/tls/certs/ca-bundle.crt"); |
| 116 | +``` |
| 117 | +
|
| 118 | +## FAQ |
| 119 | +* Why is the zip file so large? what are all those files? |
| 120 | +Typically, the zip file is large because we have to package the entire C standard library. |
| 121 | +You can reduce the size by doing some or all of the following: |
| 122 | +1. Ensure you're building in release mode `-DCMAKE_BUILD_TYPE=Release` |
| 123 | +1. If possible, build your function using musl libc, it's tiny. The easiest way to do this, assuming your code is portable, is to build on Alpine linux. |
| 124 | +* How to upload a zip file that's bigger than 50MB via the CLI? |
| 125 | +Upload your zip file to S3 first: |
| 126 | +```bash |
| 127 | +$ aws s3 cp demo.zip s3://mys3bucket/demo.zip |
| 128 | +``` |
| 129 | +NOTE: you must use the same region for your S3 bucket as the lambda. |
| 130 | + |
| 131 | +Then tell Lambda where to get it from: |
| 132 | +```bash |
| 133 | +$ aws lambda create-function --function-name demo \ |
| 134 | +--role <specify role arn here> \ |
| 135 | +--runtime provided --timeout 15 --memory-size 128 \ |
| 136 | +--handler demo |
| 137 | +--code "S3Bucket=mys3bucket,S3Key=demo.zip" |
| 138 | +``` |
| 139 | + |
| 140 | +## License |
7 | 141 | This library is licensed under the Apache 2.0 License. |
0 commit comments