はじめに
この記事は BeeX Advent Calendar 2020 の12/20の記事です。
==
12/16にLambdaでEmbulkコマンドを実行する記事を書きました。
この時はpythonのベースイメージを使用して実行しましたが、よくよく考えるとBashで実行できるのであればそっちのほうが余計な実装が不要なので、同じことをLambdaのカスタムランタイムを使用してやってみました。
以下を参考にさせていただいています。
Embulk以外の詳細はこちらをご確認ください。
環境
PC:Windows 10
Docker:Docker version 19.03.13, build 4484c46d9d
前提
Dockerの初期設定は完了済み
AWSアカウントは作成済み
Amazon ECRリポジトリは作成済み
実際の操作
bootstrap.shの作成
handler.shを呼び出すbootstrap.shを作成します。
#!/bin/sh
export _HANDLER=/aws/handler.sh
if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
exec /usr/local/bin/aws-lambda-rie $_HANDLER
else
exec $_HANDLER
fi
handler.shの作成
実際の処理を行うhandler.shを作成します。
handler関数にはembulkコマンドを記述します。
#!/bin/sh
handler(){
echo "start function"
echo "run emulk"
/usr/bin/embulk help
echo "end function"
}
while true
do
HEADERS="$(mktemp)"
# Get an event. The HTTP request will block until one is received
EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
# Extract request ID by scraping response headers received above
REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Run the handler
handler ${EVENT_DATA}
# Send the response
curl -s -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "OK"
done
Dockerfileの作成
イメージを作成するためのDockerfileを作成します。
correttoをインストールしているのはEmbulkコマンドにjavaが必要なためです。
FROM amazon/aws-cli
RUN curl -L -o /usr/local/bin/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie
RUN chmod 755 /usr/local/bin/aws-lambda-rie
RUN amazon-linux-extras enable corretto8
RUN yum install java-1.8.0-amazon-corretto-devel -y
COPY embulk /usr/bin/embulk
RUN chmod +x /usr/bin/embulk
ADD ./bootstrap.sh /aws/bootstrap
ADD ./handler.sh /aws/handler.sh
RUN chmod +x /aws/handler.sh
RUN chmod +x /aws/bootstrap
ENTRYPOINT ["/aws/bootstrap"]
イメージをビルドする
特定のフォルダに作成した以下のファイルを格納します。
$ ls
Dockerfile bootstrap.sh embulk handler.sh
ビルドコマンドを実行し、イメージを作成します。
$ docker build -t lambda_embulk_shell .
~build実行中~
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
lambda_embulk_shell latest 8b25a817b50c 15 seconds ago 428MB
テスト
ローカルで実行できるか以下のコマンドでテストをしてみます。
※curlコマンドは別ターミナル
$ docker run -p 9000:8080 lambda_shell:latest
$ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d'{}'
問題なさそうです。
$ docker run -p 9000:8080 lambda_embulk_shell:latest
time="2020-12-20T03:32:24.907" level=info msg="exec '/aws/handler.sh' (cwd=/aws, handler=)"
time="2020-12-20T03:32:29.614" level=info msg="extensionsDisabledByLayer(/opt/disable-extensions-jwigqn8j) -> stat /opt/disable-extensions-jwigqn8j: no such file or directory"
time="2020-12-20T03:32:29.614" level=warning msg="Cannot list external agents" error="open /opt/extensions: no such file or directory"
START RequestId: da60f400-e93c-4341-accc-52c680834281 Version: $LATEST
start function
run emulk
Embulk v0.9.23
Usage: embulk [-vm-options] <command> [--options]
Commands:
mkbundle <directory> # create a new plugin bundle environment.
bundle [directory] # update a plugin bundle environment.
run <config.yml> # run a bulk load transaction.
cleanup <config.yml> # cleanup resume state.
preview <config.yml> # dry-run the bulk load without output and show preview.
guess <partial-config.yml> -o <output.yml> # guess missing parameters to create a complete configuration file.
gem <install | list | help> # install a plugin or show installed plugins.
new <category> <name> # generates new plugin template
migrate <path> # modify plugin code to use the latest Embulk plugin API
example [path] # creates an example config file and csv file to try embulk.
selfupdate [version] # upgrades embulk to the latest released version or to the specified version.
ECRリポジトリへのPush
以下のコマンドでECRにPushします。
$ docker tag lambda_embulk_shell:latest XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-embulk-shell
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker push XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-embulk-shell:latest
Lambda作成・実行
Lambdaは前回使用したものを流用します。
やることはLambdaで指定しているイメージを変更するだけです。
おわりに
普段Lambdaではpythonを使用するので前回は使ってましたが、コマンドを実行したいだけならpythonである必要性もないので、カスタムランタイムを使用してみました。
実は当初はpythonで実装しようと進めていたのですが、pythonのsubprocessだとデバッグがしにくく、それならshellで実行できたほうが楽だなと思って途中で内容を修正した、という背景もあったりします。
この流れで次回はEmbulkのサンプルファイルを使用した実際の処理の実行を検証してみたいと思っています。