2022/7/13にAWSのLocalStackがバージョン1.0に到達してGAになったので、簡単に使い方を確認したいと思います。
この記事では環境構築にコンテナを利用します。Docker, Docker Composeをご準備ください。
環境
OSはWindows11です。
(Docker, Docker Composeが使用できるならば、その他OSでも動作するように考慮しているつもりですが、動作確認ができていないです...。)
$ ver
Microsoft Windows [Version 10.0.22000.856]
$ docker -v
Docker version 20.10.17, build 100c701
引用元 | https://github.com/docker/compose
$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c
LocalStackとは?
LocalStackは、AWSのリソースをローカルで再現できます。
オフラインでAWSに接続できない場合でも、AWSリソースのモックとして使用することで、開発やテストをできる便利なツールです。
flavorによる機能の違い
LocalStackには料金プランとして数種類のflavorがあります。
引用元 | LocalStack - Pricing
Community版は無料で利用できますが、使用できるAWSリソースが一部に限られます。また、データの永続化はできません。
Pro版はすべてのAWSリソースとデータの永続化が可能です。
データ永続化について
flavorによる機能の違いで紹介した通り、Community版のデータの永続化はできません。しかし、バージョン0.13.0まではサポートされていました。それ以前の旧バージョンを使用することで可能です。
基本的には最新版を使用する方がよいと思いますが、データの永続化を行いたい場合は、後述する環境構築のLocalStackのダウンロードの手順で0.13.0以前のバージョンを指定して使用してください。
環境構築
演習用資材
ソースコードは私のGitHubのlocalstack-exercise
にあります。
ローカルの任意のフォルダにダウンロードします。
git clone https://github.com/Shoma-progr-0210/localstack-exercise.git
https://github.com/Shoma-progr-0210/localstack-exercise/archive/refs/heads/main.zip
LocalStack
引用元 | https://localstack.cloud/
ダウンロードしたlocalstack-exercise
の直下LocalStackもダウンロードします。
git clone https://github.com/localstack/localstack.git
https://github.com/localstack/localstack/archive/refs/heads/master.zip
フォルダ構成が以下になっていればOKです。
localstack-exercise <- Shoma-progr-0210/localstack-exercise
├─exercises
├─exercise_container
│ └─appendix
├─localstack <- localstack/localstack
...
使ってみる
環境構築ができたら、いくつかのAWSリソースを作成してみます。
今回は最終的に以下のようなSQS + Lambda + S3のサーバレスアーキテクチャのシステムをローカルで再現します。
- AWS CLIでSQSキューにメッセージを送信する
- Lambda関数がSQSキューをポーリングしてメッセージを処理する
- Lambda関数がメッセージ処理結果をファイルとしてS3に保存する
- AWS CLIでS3からファイルをダウンロードして確認する
最初にすること
まず、localstack
コンテナとexercise
コンテナを起動します。
# localstackコンテナの起動
docker-compose -f ./localstack/docker-compose.yml up -d
# exerciseコンテナの起動
docker-compose -f ./exercise_container/docker-compose.yml up -d
exercise
コンテナに入ります。AWS CLIが使用できるLinux環境です。
docker exec -it exercise /bin/bash
これ以降のコマンドはexerciseコンテナ内です。
LocalStackはエンドポイントURLがhttp://localhost:4566
ですが、コンテナ内からホストへの接続のためhttp://host.docker.internal:4566
です。こちらは事前にexercise
コンテナのdocker-compose.yml
で設定しているので、確認します。
echo $ENDPOINT_URL
LocalStackで使用するプロファイルを作成します。プロファイル名はlocalstack
とします。
LocalStackを使用する場合はAccess Key ID
とSecret Access Key
は適当な値で構いません。
aws configure --profile=localstack
AWS Access Key ID [None]: dummy
AWS Secret Access Key [None]: dummy
Default region name [None]: ap-northeast-1
Default output format [None]: json
あらかじめ使用する値を環境変数として設定しておきます。
LocalStackはAWS アカウント IDが000000000000
で固定です。
環境変数名 | 説明 |
---|---|
SQS_QUEUE_NAME | SQSのキュー名 |
SQS_QUEUE_URL | SQSのキューのURL |
SQS_QUEUE_ARN | SQSのキューのARN |
S3_BUCKET_NAME | S3のバケット名 |
LAMBDA_FUNCTION_NAME | Lambdaの関数名 |
CLOUDWATCH_LOG_GROUP_NAME | Lambdaのログが記録されるCloudWatchロググループ名 |
export SQS_QUEUE_NAME=words-queue
export SQS_QUEUE_URL=$ENDPOINT_URL/000000000000/$SQS_QUEUE_NAME
export SQS_QUEUE_ARN=arn:aws:sqs:ap-northeast-1:000000000000:$SQS_QUEUE_NAME
export S3_BUCKET_NAME=words-bucket
export LAMBDA_FUNCTION_NAME=words-lambda
export CLOUDWATCH_LOG_GROUP_NAME=/aws/lambda/$LAMBDA_FUNCTION_NAME
SQSの作成
aws sqs create-queue --queue-name $SQS_QUEUE_NAME --endpoint-url=$ENDPOINT_URL --profile localstack
キューの一覧は以下のコマンドで確認できます。words-queue
があると思います。
aws sqs list-queues --endpoint-url=$ENDPOINT_URL --profile localstack
{
"QueueUrls": [
"http://host.docker.internal:4566/000000000000/words-queue"
]
}
S3の作成
Lambda関数がSQSキューを処理した結果ファイルをアップロードするS3バケットを作成します。
aws s3 mb s3://$S3_BUCKET_NAME --endpoint-url=$ENDPOINT_URL --profile localstack
バケットの一覧は以下のコマンドで確認できます。words-bucket
があると思います。
aws s3 ls --endpoint-url=$ENDPOINT_URL --profile localstack
2022-08-29 12:30:26 words-bucket
Lambdaの作成
SQSキューを処理して結果ファイルをS3にアップロードするLambda関数を作成します。
Lambda関数にアップロードするスクリプトは/exercise/appendix/
にあるprocess_messages.zip
です。中身はprocess_messages.py
です。
Lambda関数からS3に接続するために、必要な値を--environment
で環境変数として設定しています。
プロファイル同様に権限系の--role
は適当で構いません。
aws lambda create-function \
--function-name $LAMBDA_FUNCTION_NAME \
--runtime python3.9 \
--zip-file fileb:///exercise/appendix/process_messages.zip \
--role test-role \
--handler process_messages.lambda_handler \
--environment "Variables={AWS_ACCESS_KEY_ID=dummy,AWS_SECRET_ACCESS_KEY=dummy,REGION_NAME=ap-northeast-1,ENDPOINT_URL=$ENDPOINT_URL,BUCKET_NAME=$S3_BUCKET_NAME}" \
--endpoint-url=$ENDPOINT_URL --profile localstack
Lambda関数の一覧は以下のコマンドで確認できます。words-lambda
があると思います。
aws lambda list-functions --endpoint-url=$ENDPOINT_URL --profile localstack
{
"Functions": [
{
"FunctionName": "words-lambda",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:000000000000:function:words-lambda",
"Runtime": "python3.9",
"Role": "test-role",
"Handler": "process_messages.lambda_handler",
...省略
SQSに対するLambdaのマッピングの作成
LambdaがSQSキューをイベントとして受け取れるようにイベントソースマッピングを作成します。
--batch-size
は1回のイベントで受け取るSQSキューの数です。
aws lambda create-event-source-mapping \
--function-name $LAMBDA_FUNCTION_NAME \
--batch-size 2 \
--event-source-arn $SQS_QUEUE_ARN \
--endpoint-url=$ENDPOINT_URL --profile localstack
全体動作確認
これですべてのリソースを作成したので、動作確認をしてみましょう。
SQSキューにメッセージを送信するとLambda関数が処理してS3に結果ファイルがアップロードされるはずです。
/exercise/appendix/sqs_input_msg_00x.json
を使用してメッセージを送信します。
aws sqs send-message --queue-url $SQS_QUEUE_URL --message-body file:///exercise/appendix/sqs_input_msg_001.json --endpoint-url=$ENDPOINT_URL --profile localstack
aws sqs send-message --queue-url $SQS_QUEUE_URL --message-body file:///exercise/appendix/sqs_input_msg_002.json --endpoint-url=$ENDPOINT_URL --profile localstack
aws sqs send-message --queue-url $SQS_QUEUE_URL --message-body file:///exercise/appendix/sqs_input_msg_003.json --endpoint-url=$ENDPOINT_URL --profile localstack
数十秒後にS3バケットを確認しましょう。
s3 ls
コマンドでs3://{S3バケット名}
を指定することでS3バケット内の全てのオブジェクトを確認できます。queue_output_msg_{メッセージID}.json
の名前のファイルが3つあるはずです。
aws s3 ls s3://$S3_BUCKET_NAME --endpoint-url=$ENDPOINT_URL --profile localstack
2022-08-29 13:40:50 82 queue_output_msg_3c5bb5e4-913a-405c-8b62-5b5f50980a98.json
2022-08-29 13:40:50 84 queue_output_msg_be389e20-9422-4a66-a570-33a5243f02cb.json
2022-08-29 13:40:50 94 queue_output_msg_e3b02c32-0eda-4d70-9ee1-f71e37684d69.json
それらのファイルをダウンロードして確認できます。
ダウンロード先は/tmp/exercise/
にします。ホスト側の./exercise_container/tmp/
にボリュームマウントしてあるのでホスト側でも確認できます。
ダウンロードしたファイルのJSONにsentence
フィールドがあればOKです。
aws s3 cp s3://$S3_BUCKET_NAME/ /tmp/exercise/ --recursive --endpoint-url=$ENDPOINT_URL --profile=localstack
{"id": "001", "name": "Alice", "word": "What's up?", "sentence": "Alice said, \"What's up?\""}
{"id": "002", "name": "Bob", "word": "Hello.", "sentence": "Bob said, \"Hello.\""}
{"id": "003", "name": "Charlie", "word": "Hi!", "sentence": "Charlie said, \"Hi!\""}
おわりに
「使ってみる」と軽く題をつけて始めたものの、結構重めの内容となってしまいました。
サーバレスのAWSリソースはローカルでモックを用意しづらいイメージだったのと、SQSを学んでみたかったので、LocalStackを使ってみて良かったと思います。
ただ、無料のCommunity版だとデータの永続化ができないのはショックでした。ライトユーザーはAWSの無料枠でカバーしているのかもしれないですね。
プロファイルや権限周りを無視して試せる手軽さがあるので、これからもAWSリソースを気軽に試したいときに利用してみようと思います。