Help us understand the problem. What is going on with this article?

AWS SAM CLI を使って、ローカルでLambda環境を構築する

はじめに

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」あたりも試してみたいです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away