LocalStackとは
- LocalStack は「AWS をローカルで再現できるエミュレーター」で、S3・Lambda・DynamoDB・SQS など主要サービスを Docker 上で動かせる開発者向けツール
- AWSに接続しないのでコスト0
事前にdockerとAWS CLIを入れておくこと。
LocalStack は Linux 前提のツールのため、Windows では不安定になることがあるらしいです。
そのため、以下手順では、WSL上で実行しています。
LocalStack起動
- docker-compose.ymlを作成
services: localstack: container_name: localstack image: localstack/localstack:3.5 ports: - "4566:4566" - "4510-4559:4510-4559" environment: - SERVICES=s3,lambda // 今回はS3とlambda - DEBUG=1 - DEFAULT_REGION=ap-northeast-1 volumes: - "./localstack-data:/var/lib/localstack" - "/var/run/docker.sock:/var/run/docker.sock" - LocalStackを起動
docker-compose up - Healthチェック
ちゃんと返ってくればOK
curl http://localhost:4566/health
S3にファイルをアップロード
- バケット作成
aws --endpoint-url=http://localhost:4566 s3 mb s3://mybucket - バケットにアップロード
echo "hello" > test.txt aws --endpoint-url=http://localhost:4566 s3 cp test.txt s3://mybucket
LambdaでS3にアップロードしたtest.txtを取り出す
- index.jsを作成
const AWS = require("aws-sdk"); const s3 = new AWS.S3({ endpoint: `http://${process.env.LOCALSTACK_HOSTNAME}:4566`, // ポイント:LocalStackのエンドポイント s3ForcePathStyle: true, }); exports.handler = async () => { const params = { Bucket: "mybucket", Key: "test.txt", }; const data = await s3.getObject(params).promise(); const body = data.Body.toString("utf-8"); return { message: "S3から読み取り成功", content: body, }; }; - zip化(aws-sdkも同梱)
npm init -y npm install aws-sdk zip -r function.zip index.js node_modules package.json - Lambda作成
aws --endpoint-url=http://localhost:4566 lambda create-function \ --function-name read-s3 \ --runtime nodejs18.x \ --handler index.handler \ --zip-file fileb://function.zip \ --role arn:aws:iam::000000000000:role/lambda-role // ローカルなので、IAMはダミーでいいです - Lambda実行
aws --endpoint-url=http://localhost:4566 lambda invoke \ --function-name read-s3 \ output.json cat output.json - output.jsonの内容を確認
{"message":"S3から読み取り成功","content":"hello\n"}
無事ローカルで実行できました!
最後に
意外と詰まりポイントがあって試行錯誤しました。
LocalStackのLambdaにはaws-sdkがプリインストールされておらず、index.jsのみをzip化して実行できなかったり、
index.jsでlocalhostを参照したため、LocalStackではなくLambdaコンテナ自身を参照してしまったり(LocalStackコンテナとLambdaコンテナは別で作られるっぽい)