🐕🦺
[AWS]Lambdaでシェルスクリプトを定期実行する環境を作成
背景
EC2上でcronにより定期実行しているシェルスクリプトを、コスト削減の観点からAWS Lambdaへ移行を検討する
方針
- 定期実行はEventBridgeをトリガーとしてLambda
- Lambdaカスタムランタイムを使用
- OSはAmazonLinux2023を使用
ファイル群
- bootstrap
- シェルスクリプト
- Dockerfile
これらのファイルを用意する
bootstrap
bootstrapはAWS公式チュートリアルのものを使用
bootstrap
#!/bin/sh
set -euo pipefail
# Initialization - load function handler
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
# Processing
while true
do
HEADERS="$(mktemp)"
# Get an event. The HTTP request will block until one is received
EVENT_DATA=$(curl -sS -LD "$HEADERS" "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 function from the script
RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
# Send the response
curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
シェルスクリプト
実行するシェルスクリプトはAWS公式チュートリアルのものを使用
適宜シェルスクリプトは環境に合わせ修正してください。
function.sh
function handler () {
EVENT_DATA=$1
echo "$EVENT_DATA" 1>&2;
RESPONSE="Echoing request: '$EVENT_DATA'"
echo $RESPONSE
}
Dockerfile
シェルスクリプトが最低限動くコンテナを用意
Dockerfile
FROM public.ecr.aws/lambda/provided:al2023
COPY bootstrap ${LAMBDA_RUNTIME_DIR}
COPY function.sh ${LAMBDA_TASK_ROOT}
RUN chmod +x ${LAMBDA_RUNTIME_DIR}/bootstrap \
&& chmod +x ${LAMBDA_TASK_ROOT}/*.sh
CMD [ "function.handler" ]
AWS構築
前提としてAWS CLIが叩けること
コマンド内の[AccountID]は適宜修正
LambdaデプロイのためECRを準備する
$ aws ecr create-repository --repository-name demo --encryption-configuration encryptionType=AES256 --image-scanning-configuration scanOnPush=false
Dockerクライアントの認証
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin [AccountID].dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
イメージ作成
$ docker buildx build --platform linux/amd64 --provenance=false -t demo .
イメージにタグ付け
$ docker tag demo:latest [AccountID].dkr.ecr.ap-northeast-1.amazonaws.com/demo:latest
イメージをECRにプッシュ
$ docker push [AccountID].dkr.ecr.ap-northeast-1.amazonaws.com/demo:latest
Lambdaの作成
$ aws lambda create-function --function-name demo --package-type Image --code ImageUri="[AccountID].dkr.ecr.ap-northeast-1.amazonaws.com/demo:latest" --role [RoleARN] --timeout 30 --memory-size 512
コンソールで作る場合はコンテナイメージを選択する

テスト実行することでイベントデータが出力される。
参考
AWSチュートリアルLambda カスタムランタイムの構築
Discussion