こんにちは。プロダクトエンジニアリング部の杉本です。
この記事は、UniFaアドベントカレンダー2020 の16日目の記事になります。
(私事ですが、2020年6月にユニファにjoinして半年がたち、初めてのブログ投稿です!)
皆さんは、AWSマネージドサービスに依存する機能を開発する場合、ローカルでどのように動作確認をされていますか?
- 実際のAWS環境にローカルから接続する
- レスポンスをスタブ化する*1
- ローカルはそこそこに、とりあえず検証環境にデプロイして確認する
他にも様々あり、プロジェクトのフェーズや事情によっていずれも選択肢になりえると思います。
でもそれに相まって、多少なりともかかるコスト、誤接続や誤操作によるリスク、動作確認不十分な品質 など課題もでてきますよね。。。
今回は、そんなときにオススメな LocalStackを紹介したいと思います。
LocalStackとは
LocalStack provides an easy-to-use test/mocking framework for developing Cloud applications.
LocalStackは、ローカル環境においてAWSの各マネージドサービスと同じ機能、APIを提供してくれます。
AWSのモックサービスにはmotoやElasticMQなど有名なものが多くありますね。
LocalStackも内部的にはこれらを利用しています。
導入も容易で
pip
によるインストール- Dockerイメージの利用*2
のいずれかで可能で、READMEのOverviewにある通りCommunity版だけでも相当数のマネージドサービスをエミュレートすることができます。
ちなみに、GCPやAzureにはLocalStackほどのツールは(調べた限りでは)ありませんが、特にストレージ、メッセージングサービスについては公式のエミュレータが存在します。
cloud.google.com docs.microsoft.com
LocalStackの使い方
使い方、といってもLocalStackはエンドポイントを指定してCLIなどでリソースや設定を作成していくだけです。
なので「使ってみた」というのは割愛しますが、導入時にはいくつかポイントがあります。
LocalStackは、基本的に設定ファイルのようなものがなく、環境変数に諸々を設定していくことになります。
version: '2' services: ... localstack: image: localstack/localstack ports: - "4566:4566" environment: DATA_DIR: /tmp/localstack DEFAULT_REGION: ap-northeast-1 # default: us-east-1 HOSTNAME_EXTERNAL: localstack SERVICES: sns,sqs volumes: - ./localstack/init_scripts:/docker-entrypoint-initaws.d - localstack_tmp:/tmp/localstack ...
あくまで一部なので、詳細や他の設定はConfigurationsをご覧ください
PORTS
"LocalStack"で検索すると、サービスごとのポート一覧をまとめている記事がいくつかヒットします。
LocalStackは過去には1サービスにつき1つのポートがバインドされていましたが、しばらくの併用期間の後にv0.11.5
からは4566
番ポートのみを介して提供するようになっています。(Pro版のWebUIのみ8080
)
サービスごとには<SERVICE>_PORT_EXTERNAL
でポートを指定することも可能です。
DATA_DIR
永続化データを保存するディレクトリを指定することができます。
本記事の執筆時点では、下記のサービスのみ永続化が可能です。
- Kinesis
- DynamoDB
- Elasticsearch
- S3
- Secretsmanager
- SSM
- SQS
- SNS
HOSTNAME_EXTERNAL
SQSのQueueURLなどリソース情報にホスト名が含まれる場合、デフォルトではホスト名はlocalhost
になります。
しかしアプリケーションのコンテナ
→LocalStackのコンテナ
へリクエストするときのホスト名は、前述のdocker-compose.ymlではlocalstack
になるため、QueueURLが見つからずエラーが発生することになります。
この場合はあらかじめHOSTNAME_EXTERNAL
に、docker-compose.ymlのサービス名を設定し、外部公開用のホスト名を上書いておくことで解決することができます。
# aws sqs list-queues --endpoint-url http://localhost:4566 # default で作成した場合のqueue_url http://localhost:4566/000000000000/localstack_queue # HOSTNAME_EXTERNAL=localstack で作成した場合のqueue_url http://localstack:4566/000000000000/localstack_queue
SERVICES
LocalStackで起動するサービスはSERVICES
で指定します。
SERVICES: s3,sns,sqs
ものによってはグルーピングされていて(管理のうえで便利かはわかりませんが)面白いところです。
localstack/bootstrap.py at master · localstack/localstack · GitHub
# composites define an abstract name like "serverless" that maps to a set of services API_COMPOSITES = { 'serverless': ['cloudformation', 'cloudwatch', 'iam', 'sts', 'lambda', 'dynamodb', 'apigateway', 's3'], 'cognito': ['cognito-idp', 'cognito-identity'] }
LocalStackをより便利に使うために
リソースの初期化
S3バケットやSQSキューなど、あらかじめ必要と分かっているリソースを、開発メンバーそれぞれが毎回作成するのはとても面倒ですね。
LocalStackでは/docker-entrypoint-initaws.d
ディレクトリ配下にスクリプト*.sh
を配置すると、サービス起動後にこれを実行してくれます。
(ディレクトリパスはINIT_SCRIPTS_PATH
で変更可)
さらにLocalStackにはawslocal
というaws cli
をラップしたツールがあり、これがまた便利です。
↓は例としてSQSのキュー&デッドレターキューを作成するスクリプトです。
#!/bin/sh awslocal sqs create-queue --queue-name localstack_dead_letter_queue awslocal sqs create-queue --queue-name localstack_queue \ --attributes '{"RedrivePolicy": "{\"deadLetterTargetArn\":\"arn:aws:sqs:ap-northeast-1:000000000000:localstack_dead_letter_queue\",\"maxReceiveCount\":3}"}'
LocalStackの起動時に作成されるので、開発メンバーそれぞれがリソース有無を意識する必要がないのは、非常に便利ですね!
サービスのヘルスチェック
LocalStackは、LocalStackそのものが立ち上がったあとに SERVICES
で指定したサービスを順次起動していきます。
そのため、例えばdocker-composeを使用した場合に depends_on
で指定しても、サーバープロセス起動とほぼ同時にAWSに繋ぎにいくようなサービスである場合は、Connection Errorが出ることになります。
ローカルであればさほど問題ではありませんが「LocalStackを自動テストに組み込みたい」など要望によっては厳密にしたいことがあります。
そんなときは、LocalStackにはヘルスチェック用のエンドポイントが用意されているので、これを活用することができます。
$ curl -s http://localhost:4566/health | jq { "services": { "sns": "running", "sqs": "running" } }
Pro版を活用する
LocalStackはCommutiny版でも十分に便利ですが、Pro版*3ではWeb UI(Community版は aws cli
での操作)に加えてElastiCache、S3 Selectなどより多くのサービスを使用することができるようになります。
LocalStack comes in two flavors - as a free, open source Base Edition, and as a Pro Edition with extended features and support. See the table below for a comparison. If you need support for large organizations, please contact us for the Enterprise Edition.
プロジェクトによって「何を、どこまで、確認したいのか」は様々ですし、LocalStack上に必要なリソースや設定を作成していく手間もあるので、あとは諸々とご相談ですね。
最後に
LocalStackは無料かつローカルで使用できるので
- Terraformのお試し実行環境
- AWSを学び始めた方の練習環境
としても有用です。上手く活用して、開発の品質も効率も高めていきたいですね!
ユニファでは、継続的にサービスを改善していきたいエンジニア、デザイナー、プロダクトマネージャーを積極採用中です!
最後までお読みいただき、ありがとうございました!