Posted at

LocalstackとDocker ComposeでCloud Native Applicationをローカルで動かす

More than 1 year has passed since last update.


LocalstackとDocker ComposeでCloud Native Applicationをローカルで動かす

WebアプリケーションがAWSサービスに依存するときに開発環境をどう整えるか、色々調べましたが一番有力と思ったのがLocalstackでした。

本記事で、簡単な紹介とサンプルを記載していきます。


  • LocalstackをDocker-Composeで動かす

  • Lambda関数を登録する

  • WEBアプリケーションをDocker-Composeで動かす

  • WEBアプリケーションからLambda関数を呼び出す

IMG_5815.JPG


LocalstackをDocker-Composeで動かす

LocalstackはAWSアービスのモック・テストツールで、Lambda関数、SQSキュー、DynamoDBなどをローカル環境で動かしてテスト実行や開発環境として使えます。


https://localstack.cloud/


Pipでインストールしたくないので、レポジトリをcloneしてDocker-composeで動かします。

$ git clone https://github.com/localstack/localstack.git


$ cd localstack

$ export TMPDIR=/private$TMPDIR
$ export SERVICES=lambda

$ docker-compose up

起動後、 http://localhost:8080 でコンソールをアクセスできます。


Lambda関数を登録する

登録はAWSでやるときとは変わらないので、Hello World程度のもので記載します。

環境変数を設定し、AWS CLIが使えるようにします。

$ export AWS_ACCESS_KEY_ID=dummy

$ export AWS_SECRET_ACCESS_KEY=dummy
$ export AWS_DEFAULT_REGION=ap-northeast-1
$ export AWS_DEFAULT_OUTPUT=text

次は簡単なPythonコードでLambda関数のソースを用意します。


my_lambda_function.py

def lambda_handler(event, context):    

print(event)

$ FUNCTION_NAME=MY_LAMBDA_FUNCTION

$ PYTHON_RUNTIME=python2.7

$ zip "./lambda_function.zip" ./my_lambda_function.py

$ aws --endpoint-url=http://localhost:4574 lambda create-function \
--function-name="${FUNCTION_NAME}" \
--runtime="${PYTHON_RUNTIME}" \
--role=r1 \
--handler=my_lambda_function.lambda_handler \
--zip-file "fileb://lambda_function.zip"


WEBアプリケーションをDocker-Composeで動かす

WEBアプリケーションは別のDocker-Composeファイルで定義されていますが、そのままですとLocalstackのDockerネットワークが異なるので接続できません。

繋げるためには、WEBアプリケーションのDocker-Composeファイルにnetworkセクションを定義する必要があります。


https://docs.docker.com/compose/networking/



docker-compose.yml

...

networks:
default:
external:
name: localstack_default


WEBアプリケーションからLambda関数を呼び出す

WEBアプリケーションがRailsだとします。ポイントとしてはクライアントを作るときにendpointのキーでLocalstackのURLとポート番号を指定することです。

以下の例では cloud_deployed の変数でローカル環境かどうかを判別しています。

lambda = if cloud_deployed?

Aws::Lambda::Client.new(region: ENV['REGION'],
access_key_id: ENV['ACCESS_KEY_ID'],
secret_access_key: ENV['SECRET_ACCESS_KEY'])
else
Aws::Lambda::Client.new(region: ENV['REGION'],
endpoint: 'http://localstack:4574',
access_key_id: ENV['ACCESS_KEY_ID'],
secret_access_key: ENV['SECRET_ACCESS_KEY'])
end

あとはいつもどおり呼び出せます。

lambda.invoke(function_name: 'MY_LAMBDA_FUNCTION', payload: message)


参考記事