LoginSignup
22
28

More than 1 year has passed since last update.

【AWS】LocalStackを使ってみる

Posted at

2022/7/13にAWSのLocalStackがバージョン1.0に到達してGAになったので、簡単に使い方を確認したいと思います。
この記事では環境構築にコンテナを利用します。Docker, Docker Composeをご準備ください。

環境

OSはWindows11です。
(Docker, Docker Composeが使用できるならば、その他OSでも動作するように考慮しているつもりですが、動作確認ができていないです...。)
env.drawio.png

Windows
$ ver
Microsoft Windows [Version 10.0.22000.856]

docker.drawio.png

Docker
$ docker -v
Docker version 20.10.17, build 100c701

logo.png
引用元 | https://github.com/docker/compose

Docker Compose
$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c

LocalStackとは?

LocalStackは、AWSのリソースをローカルで再現できます。
オフラインでAWSに接続できない場合でも、AWSリソースのモックとして使用することで、開発やテストをできる便利なツールです。

flavorによる機能の違い

LocalStackには料金プランとして数種類のflavorがあります。
localstack_pricing_20220829.png
引用元 | LocalStack - Pricing

Community版は無料で利用できますが、使用できるAWSリソースが一部に限られます。また、データの永続化はできません。
Pro版はすべてのAWSリソースとデータの永続化が可能です。

データ永続化について
flavorによる機能の違いで紹介した通り、Community版のデータの永続化はできません。しかし、バージョン0.13.0まではサポートされていました。それ以前の旧バージョンを使用することで可能です。
基本的には最新版を使用する方がよいと思いますが、データの永続化を行いたい場合は、後述する環境構築のLocalStackのダウンロードの手順で0.13.0以前のバージョンを指定して使用してください。

環境構築

演習用資材

ソースコードは私のGitHubのlocalstack-exerciseにあります。
ローカルの任意のフォルダにダウンロードします。

Gitコマンド - Shoma-progr-0210/localstack-exercise
git clone https://github.com/Shoma-progr-0210/localstack-exercise.git
Zipファイルでダウンロード - Shoma-progr-0210/localstack-exercise
https://github.com/Shoma-progr-0210/localstack-exercise/archive/refs/heads/main.zip

LocalStack

LocalStack Logo
引用元 | https://localstack.cloud/

ダウンロードしたlocalstack-exerciseの直下LocalStackもダウンロードします。

Gitコマンド - localstack/localstack
git clone https://github.com/localstack/localstack.git
Zipファイルでダウンロード - localstack/localstack
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のサーバレスアーキテクチャのシステムをローカルで再現します。

  1. AWS CLIでSQSキューにメッセージを送信する
  2. Lambda関数がSQSキューをポーリングしてメッセージを処理する
  3. Lambda関数がメッセージ処理結果をファイルとしてS3に保存する
  4. AWS CLIでS3からファイルをダウンロードして確認する

serverless.drawio.png

最初にすること

AWSCLI.png
まず、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環境です。

exerciseコンテナに入る
docker exec -it exercise /bin/bash

これ以降のコマンドはexerciseコンテナ内です。

LocalStackはエンドポイントURLがhttp://localhost:4566ですが、コンテナ内からホストへの接続のためhttp://host.docker.internal:4566です。こちらは事前にexerciseコンテナのdocker-compose.ymlで設定しているので、確認します。

エンドポイントURLの確認
echo $ENDPOINT_URL

LocalStackで使用するプロファイルを作成します。プロファイル名はlocalstackとします。
LocalStackを使用する場合はAccess Key IDSecret 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の作成

sqs.png
SQSキューを作成します。

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の作成

s3.png
Lambda関数がSQSキューを処理した結果ファイルをアップロードするS3バケットを作成します。

S3バケットの作成
aws s3 mb s3://$S3_BUCKET_NAME --endpoint-url=$ENDPOINT_URL --profile localstack

バケットの一覧は以下のコマンドで確認できます。words-bucketがあると思います。

S3バケットの一覧
aws s3 ls --endpoint-url=$ENDPOINT_URL --profile localstack
結果
2022-08-29 12:30:26 words-bucket

Lambdaの作成

Lambda.png
SQSキューを処理して結果ファイルをS3にアップロードするLambda関数を作成します。
Lambda関数にアップロードするスクリプトは/exercise/appendix/にあるprocess_messages.zipです。中身はprocess_messages.pyです。
Lambda関数からS3に接続するために、必要な値を--environmentで環境変数として設定しています。
プロファイル同様に権限系の--roleは適当で構いません。

Lambda関数の作成
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があると思います。

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のマッピングの作成

mapping.drawio.png
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を使用してメッセージを送信します。

SQSキューにメッセージ送信
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つあるはずです。

S3バケット内のオブジェクト一覧
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です。

S3バケットのオブジェクトダウンロード
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リソースを気軽に試したいときに利用してみようと思います。

22
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
28