OS | アーチ | 状態 |
---|---|---|
アマゾン リナックス 2 | x86_64 | |
アマゾン リナックス 2 | aarch64 | |
Amazon Linux (ALAMI) | x86_64 | |
高山 | x86_64 | |
Arch Linux | x86_64 | |
Ubuntu 18.04 | x86_64 |
Lambda ランタイム API の C++ 実装
AWS Lambda は GNU/Linux 上で実行されるため、このランタイム ライブラリとロジックも GNU/Linux 上で構築する必要があります。
最初に次のパッケージがインストールされていることを確認してください。
ターミナルで次のコマンドを実行します。
$ git clone https://github.com/awslabs/aws-lambda-cpp.git
$ cd aws-lambda-cpp
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX= ~ /lambda-install
$ make && make install
CMake も使用しているプロジェクトでこのライブラリを使用するには、次のようにします。
cmake_minimum_required ( VERSION 3.9)
set (CMAKE_CXX_STANDARD 11)
project (demo LANGUAGES CXX)
find_package (aws-lambda-runtime)
add_executable ( ${PROJECT_NAME} "main.cpp" )
target_link_libraries ( ${PROJECT_NAME} PRIVATE AWS::aws-lambda-runtime)
target_compile_features ( ${PROJECT_NAME} PRIVATE "cxx_std_11" )
target_compile_options ( ${PROJECT_NAME} PRIVATE "-Wall" "-Wextra" )
# this line creates a target that packages your binary and zips it up
aws_lambda_package_target( ${PROJECT_NAME} )
main.cpp
サンプルは次のようになります。
# include < aws/lambda-runtime/runtime.h >
using namespace aws ::lambda_runtime ;
static invocation_response my_handler (invocation_request const & req)
{
if (req. payload . length () > 42 ) {
return invocation_response::failure ( " error message here " /* error_message */ ,
" error type here " /* error_type */ );
}
return invocation_response::success ( " json payload here " /* payload */ ,
" application/json " /* MIME type */ );
}
int main ()
{
run_handler (my_handler);
return 0 ;
}
最後に、すべてをパッケージ化する方法を示します。アプリケーションのルート ディレクトリから次のコマンドを実行します。
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX= ~ /lambda-install
$ make
$ make aws-lambda-package-demo
上記の最後のコマンドmake aws-lambda-package-demo
demo.zip
という zip ファイルを現在のディレクトリに作成します。
次に、AWS CLI を使用して IAM ロールと Lambda 関数を作成します。
まず、次の信頼ポリシー JSON ファイルを作成します。
$ cat trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": ["lambda.amazonaws.com"]
},
"Action": "sts:AssumeRole"
}
]
}
次に、IAM ロールを作成します。
$ aws iam create-role --role-name lambda-demo --assume-role-policy-document file://trust-policy.json
コマンドの実行後に Arn から返されたロールをメモします。次のステップで必要になります。
次のポリシーをアタッチして、Lambda が CloudWatch にログを書き込むことを許可します。
$ aws iam attach-role-policy --role-name lambda-demo --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
使用する予定の他の AWS サービスに対して、必ず適切なポリシーやアクセス許可をアタッチしてください。
最後に、Lambda 関数を作成します。
$ aws lambda create-function --function-name demo
--role
--runtime provided --timeout 15 --memory-size 128
--handler demo --zip-file fileb://demo.zip
そして関数を呼び出すには:
$ aws lambda invoke --function-name demo --payload ' {"answer":42} ' output.txt
このライブラリは、AWS C++ SDK から完全に独立しています。 AWS C++ SDK は、アプリケーション内の単なる別の依存関係として扱う必要があります。この Lambda ランタイムで AWS C++ SDK を利用するデモについては、例セクションを参照してください。
GNU/Linux x86-64 をターゲットとする完全準拠の C++11 コンパイラであれば動作するはずです。中途半端な C++11 サポートを提供するコンパイラ バージョンは避けてください。
Lambda は、Amazon Linux の一部のバージョンでコードを実行します。そのプラットフォーム上でのみアプリケーションを構築する必要がある場合、それは理想的な顧客エクスペリエンスとは言えません。
ただし、Linux ディストリビューション上に自由に構築できることには課題が伴います。 GNU C ライブラリ ABI。 Lambda 関数の構築に使用されるプラットフォームが、AWS Lambda で使用されるものと同じ GLIBC バージョンを持つという保証はありません。実際、GNU の実装を使用していない可能性もあります。たとえば、musl libc を使用して C++ Lambda 関数を構築できます。
アプリケーションが Lambda 上で正しく実行されるようにするには、C ランタイム ライブラリ全体を関数とともにパッケージ化する必要があります。 lambda で使用されているのと同じ Amazon Linux バージョン上に構築することを選択した場合は、C ランタイムを zip ファイルにパッケージ化する必要がなくなります。これは、次のように CMake でNO_LIBC
フラグを渡すことで実行できます。
aws_lambda_package_target( ${PROJECT_NAME} NO_LIBC)
dlopen
経由で動的にロードされる Lambda 関数のライブラリ依存関係は、自動的にはパッケージ化されません。これらの依存関係を zip ファイルに手動で追加する必要があります。これは、コードが依存するすべての構成ファイルまたはリソース ファイルに適用されます。
TLS (https) 経由で HTTP 呼び出しを行っている場合は、CA バンドルの場所がディストリビューション間で異なることに注意してください。たとえば、AWS C++ SDK を使用している場合は、次の構成オプションを設定するのが最適です。
Aws::Client::ClientConfiguration config;
config.caFile = " /etc/pki/tls/certs/ca-bundle.crt " ;
AWS C++ SDK を使用していないが、たまたま libcurl を直接使用している場合は、次の手順で CA バンドルの場所を設定できます。
curl_easy_setopt ( curl_handle , CURLOPT_CAINFO , "/etc/pki/tls/certs/ca-bundle.crt" );
zip ファイルがこんなに大きいのはなぜですか?これらのファイルは何ですか? C 標準ライブラリ全体をパッケージ化する必要があるため、通常、zip ファイルは大きくなります。次の一部またはすべてを実行すると、サイズを縮小できます。
-DCMAKE_BUILD_TYPE=Release
CLI 経由で 50MB を超える zip ファイルをアップロードするにはどうすればよいですか?まず zip ファイルを S3 にアップロードします。
$ aws s3 cp demo.zip s3://mys3bucket/demo.zip
注: S3 バケットにはラムダと同じリージョンを使用する必要があります。
次に、次の方法で Lambda 関数を作成できます。
$ aws lambda create-function --function-name demo
--role < specify role arn here >
--runtime provided --timeout 15 --memory-size 128
--handler demo
--code " S3Bucket=mys3bucket,S3Key=demo.zip "
コードがクラッシュします。どうすればデバッグできますか?
sudo apt install libdw-dev
またはsudo apt install binutils-dev
sudo yum install elfutils-devel
またはsudo yum install binutils-devel
これらのパッケージのいずれかがインストールされている場合、CMake はそれらを検出し、自動的にリンクします。他の手順は必要ありません。-DCMAKE_BUILD_TYPE=Debug
。詳細ログは、デバッグ ビルドではデフォルトで有効になっています。-DLOG_VERBOSITY=3
を使用してランタイムをビルドします。$ docker run -v /tmp:/tmp -it --security-opt seccomp=unconfined amazonlinux:2017.03
security-opt
引数は、 gdb
、 strace
などを実行します。SSL CA 証明書の CURL の問題
libcurl
バージョン、またはそのフレーバーの 1 つ (BoringSSL、LibreSSL) を使用していることを確認してください。libcurl
必ず指示してください。 std::string
とAws::String
の間の既知の変換はありません
-DBUILD_SHARED_LIBS=OFF
)。 このライブラリは、Apache 2.0 ライセンスに基づいてライセンスされています。