Edited at

LocalStack導入から実行まで

More than 1 year has passed since last update.


はじめに

最近、AWS API GateWay + Lambdaを使用して、サーバレスでWeb APIを作成する機会がありました。

AWS コンソールから関数の作成、コードの編集を行う、といった体制で進めていましたが、一つの問題が出ました。

それが「コード書き換えてしまう問題」です

具体的に説明しますと、作業者AがとあるLambda関数を編集中に、作業者Bが同じLambda関数を更新しました。

その後、作業者Aが編集内容を更新すると、作業者Bの編集した内容が消えてしまうという問題です。

当時はバージョンの発行を行なっておらず、消えてしまったコードを遡ることができませんでした(このことを機にバージョン発行を覚えました)

元々、Lambdaで作成したソースコードをGitで管理したい、ローカル環境でテストしてから反映したい、等の意見を頂いていたので、ローカルによるLambda関数の実行、バージョンの管理をテーマに調べました、

そこで出会ったのがLocalStackでした。


LocalStackとは

LocalStackは、ローカルにAWSのモック/テスト環境を作ってくれてるツールです。

イメージとしては、ローカルに擬似的なAWS環境を作ってくれて、料金など気にせずにテストや

動作確認を可能にしてくれます。

他にもツールはありましたが、LocalStackの導入が比較的簡単そうであったため、今回はこれを使用します。


要件


  • ローカルにてLambda関数の実行

  • ソースコードをGitにて管理

  • AWS Lambda反映時に自動でバージョンを作成


環境


  • OS: macOS High Sierra(10.13.2)

  • Lambda ランタイム: Python3.6


事前準備


docker, docker-composeのインストール

公式サイトはコチラ


aws-cliのインストール

$ brew install awscli


aws アクセスキーの発行

公式サイトにて方法が記載されているので、各自発行してください。


aws プロファイルの設定

$ aws configure --profile localstack

AWS Access Key ID [None]: アクセスキー
AWS Secret Access Key [None]: シークレットキー
Default region name [None]: ap-northeast-1
Default output format [None]: text


jqコマンドのインストール

$ brew install jq



LocalStack導入手順


LocalStackインストール&起動

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

$ cd localstack
$ TMPDIR=/private$TMPDIR docker-compose up -d

上記実行後、http://localhost:8080にてlocalstackのダッシュボート表示

スクリーンショット 2018-01-23 17.35.16.png


Lambda関数作成

$ mkdir 任意の作業ディレクトリ名

$ cd 任意の作業ディレクトリ名
$ vi lambda.py


lambda.py

# サンプルコードです

def lambda_handler(event, context):
return 'Hello from Lambda'


localstack上にLambda関数を作成


  1. zipで固める

$ zip lambda.zip lambda.py


  1. localstack上に作成

$ aws --endpoint-url=http://localhost:4574 --region ap-northeast-1 --profile localstack lambda create-function --function-name="作成する関数名" --runtime=python3.6 --role="実行ロール名" --handler=lambda.lambda_handler --zip-file fileb://lambda.zip

スクリーンショット 2018-01-24 11.01.33.png


lambda関数実行

$ aws lambda --endpoint-url=http://localhost:4574 invoke --function-name "実行する関数名" --payload '{"key1":"value1", "key2":"value2", "key3":"value3"}' result.log

200

200が返って来たら成功


レスポンスの確認

$ cat result.log | jq

result.logをjqコマンドでJSON形式に変換して出力することで確認できます。



localstack上のlambda関数の一覧取得

$ aws --endpoint-url=http://localhost:4574 --region ap-northeast-1 --profile localstack lambda list-functions


localstack上のlambda関数の削除

$ aws --endpoint-url=http://localhost:4574 --region ap-northeast-1 --profile localstack lambda delete-function --function-name "削除する関数名"


localstack上のlambda関数の更新

$ aws --endpoint-url=http://localhost:4574 --region ap-northeast-1 --profile localstack lambda update-function-code --profile localstack --function-name "更新する関数名" --zip-file fileb://lambda.zip --publish


感想

dockerでローカルにawsテスト用のエンドポイントを作成し、awscliでlambda関数をLocalStackにあげて実行するような形です。

コマンドが少し長くて大変ですが、そこはエイリアスを設定したりでカバーできたらと思っています。

lambda関数の実行/作成/削除/更新のコマンドオプションに--endpoint-url=http://localhost:4574という指定があります。

これがLocalStackでの実行を指定しており、このオプションをつけないことによって、運用しているAWSに対して直接lambda関数の作成や更新など行うことができるため、localでテストしてすぐ本番に反映できるような感じです。

lambda関数更新時は、Lambda側が勝手にバージョンを作成してくれるため、Lambda側のバージョン管理も簡単にできるように感じました。


落とし穴

Lambdaにて関数を作成した場合、ファイル名はlambda_function.拡張子で固定されています。

ローカルでファイル名をhogehoge.pyのように適当につけて、既存lambda関数に対して更新をかけると、ファイルがないと怒られて動かなくなるため、注意が必要です。(テスト環境が一時停止して結構焦りました。)



参考サイト