LoginSignup
6

More than 5 years have passed since last update.

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

Posted at

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)

参考記事

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
6