はじめに
最近、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のダッシュボート表示
Lambda関数作成
$ mkdir 任意の作業ディレクトリ名
$ cd 任意の作業ディレクトリ名
$ vi lambda.py
# サンプルコードです
def lambda_handler(event, context):
return 'Hello from Lambda'
localstack上にLambda関数を作成
- zipで固める
$ zip lambda.zip lambda.py
- 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
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関数に対して更新をかけると、ファイルがないと怒られて動かなくなるため、注意が必要です。(テスト環境が一時停止して結構焦りました。)
参考サイト
-
LocalStackをつかってローカルでLambdaを実行してみた
https://dev.classmethod.jp/cloud/aws/localstack-lambda/ -
AWS CLIのインストール
https://qiita.com/yuyj109/items/3163a84480da4c8f402c -
localstackをdockerを使ってセットアップする
https://qiita.com/liris/items/d89e88db44b4c30a6896 -
aws-cli コマンド一覧(随時追記)
https://qiita.com/bakira/items/8a9481c99ed56a367415 -
エンコードマニアックス
https://encodemaniax.com/