awsのリソースを自動展開するシステムを開発しています。リソース内部の設定が複雑でありPython SDKで実装するとコマンドの検証に不便が出てきそうな雰囲気だったためaws-cliをLambdaで実行しようと考えました。
AWSのチュートリアルを見ればファイルの構3成は把握できると思います。bootstrapがイベントをwhile true
で待ち受け、検知するとそれをパースしてイベントハンドラ(ここではfunction.sh
の関数)に投げます。その出力を以ってレスポンスとして返します。
コード
チュートリアルのコードに一部インストール用の設定を加えています。インストールを含むためテスト実行時にTimeoutエラーが出るかもしれませんが焦らずにタイムアウト時間を伸ばしましよう。
bootstrap
#!/bin/sh
set -euo pipefail
# tmpフォルダ内にawscliを配置するためHOMEとPATHを設定
export HOME="/tmp"
export PATH="$HOME/.local/bin:$PATH"
# pipをインストール
cd /tmp
curl -sSL https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py --user
# pipを用いてawscliをインストール
pip install awscli --user
# Handler format: <script_name>.<function_name>
#
# The script file <script_name>.sh must be located at the root of your
# function's deployment package, alongside this bootstrap executable.
source $(dirname "$0")/"$(echo $_HANDLER | cut -d. -f1).sh"
while true
do
# Request the next event from the Lambda runtime
HEADERS="$(mktemp)"
EVENT_DATA=$(curl -v -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
INVOCATION_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Execute the handler function from the script
RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
# Send the response to Lambda runtime
curl -v -sS -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$INVOCATION_ID/response" -d "$RESPONSE"
done
handlerでaws-cliの動作を確認する。標準エラー出力へaws-cliのバージョンが出力されるか確認します。
function.sh
function handler () {
EVENT_DATA=$1
# このhandlerの標準出力(1)がそのままbootstrapでRESPONSEになる
# よってデバッグ用echoは標準エラー出力へ逃がす必要がある
echo "$EVENT_DATA" 1>&2;
echo $(aws --version 1>&2);
RESPONSE="Echoing request: '$EVENT_DATA'"
echo $RESPONSE
}
無事に出力されれば動作しています。今回のコードではtestにデフォルトのものをそのまま利用しているため$EVENT_DATA
はデフォルトのものです。
output
{"key1":"value1","key2":"value2","key3":"value3"}
aws-cli/1.16.219 Python/2.7.16 Linux/4.14.123-95.109.amzn2.x86_64 botocore/1.12.209
to do
- aws-cliを利用した自動展開の検証
- リソース立ち上げ時間とタイムアウトの格闘