はじめに
LocalStackは、AWSの各サービスをローカルで再現するためのフェイク環境です。
公式のDockerイメージを使うと便利です。
localstack
は、AWS Summit Tokyo 2017
での@twada
の講演で聞いたことがありましたが、今回初めて使いました。
- Testable Lambda: Working Effectively with Legacy Lambda // Speaker Deck
- Testable Lambda|AWS Summit Tokyo 2017 - YouTube
Dockerコンテナ内でLocalStackを使う
下記のように、Dockerコンテナを構成していたとします。
# docker-compose.yml
version: '3'
services:
app:
build: .
env_file: .env
volumes:
- .:/app
- ~/.aws:/root/.aws
working_dir: /app
links:
- localstack
localstack:
image: localstack/localstack
ports:
- '8080:8080'
- '4576:4576' # For SQS
app
コンテナから任意のQueue
にメッセージを送信しようとすると、QueueUrl
がhttp://localhost:4576/queue/{QueueName}
となり、下記のようにエラーが発生します。
Aws\Sqs\Exception\SqsException: Error executing "SendMessage" on "http://localhost:4576/queue/{QueueName}";
AWS HTTP error: cURL error 7: Failed to connect to localhost port 4576: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
app
コンテナとlocalstack
コンテナは、別のIPアドレスになるわけで、localhost
ではなくホスト名のlocalstack
でアクセスしたいのですが、何故かlocalhost
のQueueUrl
を返してきます。
もちろん、endpoint
は、http://localstack:4576
を指定しています。
解決方法
READMEに解決方法が記載されていました。
`HOSTNAME_EXTERNAL`: Name of the host to expose the services externally (defaults to `localhost`).
This host is used, e.g., when returning queue URLs from the SQS service to the client.
要するに、環境変数HOSTNAME_EXTERNAL
にlocalstack
を指定すればいいのです。
# docker-compose.yml
localstack:
image: localstack/localstack
environment:
- HOSTNAME_EXTERNAL=localstack
無事、QueueUrl
がhttp://localstack:4576/queue/{QueueName}
となり、メッセージを送受信できるようになりました。
おわりに
@twada
が講演の中でおっしゃっていますが、LocalStack
のようなFake Object
を使うことで、テストのために、依存ライブラリをインストールする必要がなくなり、テストもスッキリしますし、素早く開発が行えます。
今回のように、つまづくポイントがあったら、一つ一つ記事にしていきたいと思います。
ではでは。