はじめに
AWS SAM CLIを使って、Lambda環境をローカルで構築できると聞いて構築してみました。
チュートリアルでオプションになっているローカルで動作させるところをゴールとしています。
なので、開発者ガイドに書かれているようなIAMやS3は設定しません。AWS CLI もインストールしません。
ローカルのLambdaは、Docker コンテナで動作します。
また、この記事では下記の開発者ガイドを参考にしています。
各コマンドが何を行っているか詳細が書かれているので、気になる方は参照してみてください。
この記事は、2019年11月時点で作業記録です。
環境
- CentOS Linux release 7.6.1810
- Docker 19.03.1
- python 3.7.5(Lambdaのruntimeが3.7なので揃えてみました)
AWS SAM CLI のインストール
pipでインストールします。
$ pip install aws-sam-cli
$ sam --version
SAM CLI, version 0.31.0
これだけです。
サンプルAWS SAMアプリケーションをダウンロードする
AWS SAM CLIのバージョンによって、ダウンロード時のコマンドが変わります。
SAM CLI version 0.30.0 より新しい場合は、下記のコマンドになります。
$ sam init --runtime python3.7 --dependency-manager pip --app-template hello-world --name sam-app
Quick start templates may have been updated. Do you want to re-download the latest [Y/n]: y
特に何も表示されずに、完了しました。
sam-app ディレクトリが出来ています。
$ cd sam-app/
$ ls
README.md events hello_world template.yaml tests
$ ls hello_world/
__init__.py app.py requirements.txt
$ ls tests/
unit
$ ls tests/unit/
__init__.py test_handler.py
template.yaml のあるディレクトリで下記コマンドを実行します。
$ sam build
Building resource 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Package: sam package --s3-bucket <yourbucket>
ビルドされたファイルを確認します。
$ ls .aws-sam/build/
HelloWorldFunction template.yaml
アプリケーションをローカルでテストする
テストには下記の2つの方法があります。
- APIを起動してリッスンさせる方法
- 1回だけ起動させる方法
順に試します。
なお、コンテナimageは、両方とも同じものを使用します。
APIを起動してリッスンさせる方法
下記コマンドで、起動します。
初回起動時には、「Fetching lambci/lambda:python3.7 Docker container image......」の記述の箇所でコンテナimageのダウンロードが始まります。
$ sam local start-api
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2019-11-12 00:10:20 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
※ここで別ターミナルを起動してcurlを実行(詳細、後述)
Invoking app.lambda_handler (python3.7)
Fetching lambci/lambda:python3.7 Docker container image......
Mounting /home/user01/python375/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: ebf27a72-6c64-15f8-7ace-996a84d48b4f Version: $LATEST
END RequestId: ebf27a72-6c64-15f8-7ace-996a84d48b4f
REPORT RequestId: ebf27a72-6c64-15f8-7ace-996a84d48b4f Duration: 6.58 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 18 MB
No Content-Type given. Defaulting to 'application/json'.
2019-11-12 00:11:32 127.0.0.1 - - [12/Nov/2019 00:11:32] "GET /hello HTTP/1.1" 200 -
crtl + c で停止します。
別のターミナルを起動して、curlを実行します。
$ curl http://127.0.0.1:3000/hello
{"message": "hello world"}
"hello world" が返ってきています。
待ち受けの間はコンテナが存在していません。
接続のたびにコンテナが起動しています。
確認のため、さらに別のターミナルを起動します。
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
005c0e19f8b4 lambci/lambda:python3.7 "/var/rapid/init --b…" 1 second ago Up Less than a second quirky_merkle
※コンテナの起動時間は、非常に短いです。curlコマンド実行後に何度も連続実行して、1回くらいしか表示されません。
1つ目のターミナルで、apiを起動。
2つ目のターミナルで、curlを実行。
3つ目のターミナルで、コンテナの確認を行っています。
1回だけ起動させる方法
下記コマンドで、起動します。
$ sam local invoke "HelloWorldFunction" -e events/event.json
Invoking app.lambda_handler (python3.7)
Fetching lambci/lambda:python3.7 Docker container image......
Mounting /home/user01/python375/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 22c90126-252a-1c9f-204a-a554f10d922b Version: $LATEST
END RequestId: 22c90126-252a-1c9f-204a-a554f10d922b
REPORT RequestId: 22c90126-252a-1c9f-204a-a554f10d922b Duration: 6.08 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 20 MB
{"statusCode":200,"body":"{\"message\": \"hello world\"}"}
最後の行で、"hello world" が返ってきています。
最後に
クラウドにデプロイしないためなのか、想像していたより簡単に実現できました。
AWS SAM CLIコマンドリファレンス に、「sam local start-lambda」の記載がありました。
まだまだ、使い方があるようです。
今回はチュートリアルにそって実行しているだけでした。
時間を見つけて、「sam local start-lambda」あたりも試してみたいです。