【AWS SAM】ローカルコンテナを活用したデプロイ前テスト・小技集

前回ブログでは、AWS SAMのインストールからAPI Gateway+Lambdaのデプロイまでを紹介しました。
今回はその延長として、SAMを使用したローカルコンテナでのデプロイ前テストや、便利な小技・トラブルシューティングを紹介します。

ローカルコンテナでLambda・API Gatewayをテストする

sam local コマンドを使うと、ローカルPC上のDockerコンテナでLambdaやAPI Gatewayを疑似的に再現してテストできます。
これにより、実際にクラウドへデプロイする前に動作確認ができ、修正やデバッグを効率的に行うことが可能になります。

Lambdaをローカルで実行

ローカル上でLambdaのテストを行えます。
sam local invokeにて、Lambdaを仮に実行した場合の結果が確認できます。

# ローカルPCにて、Lambda上の関数を実行して結果確認
$ sam local invoke

Invoking app.lambda_handler (python3.9)
Local image was not found.
Building image...
Using local image: public.ecr.aws/lambda/pythonxxx
# 結果
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}

APIをローカルで実行

ローカル上でAPI Gatewayのテストを行えます。
sam local start-apiにて、API Gatewayを仮に構築した場合のエンドポイントURLをコンテナで構築します。
ローカルホスト127.0.0.1を叩くと、API Gatewayに相当する応答が返ってきます。

$ sam local start-api

# ローカルホスト上にAPI Gatewayのエンドポイントを構築
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions.

#ブラウザやcurlで `http://127.0.0.1:3000/hello` にアクセスすると、Lambdaの応答が確認可能

【トラブルシューティング】コンテナが立ち上がらない場合

コンテナが立ち上がらない場合は、Docker Desktopをインストールして、稼働しているかを確認ください。

もしWSL2のUbuntuを使用している場合は、設定の見直しが必要な場合があります。
こちらのブログも参照ください。

【小技】SAMでクラウド上のLambda呼び出し

クラウド上で作成済みのLambdaを直接テストできます。
API Gatewayであれば、HTTPSリクエストで叩けますが、Lambdaでは一癖あります。
sam remote invokeを使用して、クラウド上のLambdaを直接叩き応答を確認できます。デプロイ後の確認に有用です。

# sam-appというプロジェクトの中のHelloWorldFunctionを呼び出し
$ sam remote invoke HelloWorldFunction --stack-name sam-app

{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}

【小技】ローカルファイル変更時のクラウド上リソースの自動同期

sam sync コマンドを使うと、ローカルコードの変更を即座にクラウドに反映できます。
ローカル上のプロジェクト内のファイルを変更し保存すると、即座に下記のようにクラウド上のリソースの上書きが起こります。

# 一旦sam syncを実行
$ sam sync --watch

# ローカルファイルを変更すると、リソースも変更される
Syncing Lambda Function HelloWorldFunction...
Finished syncing Lambda Function HelloWorldFunction.

--no-watch の場合、sam sync実行時に更新されます。
ある程度ローカルファイルを更新したうえで、まとめて上書きする際に良さそうです。

# sam syncを実行したときに、リソースが変更される
$ sam sync --no-watch

Syncing Lambda Function HelloWorldFunction...
Finished syncing Lambda Function HelloWorldFunction.

ちなみに、sam sync --watch/no-watchでは、クラウド上のリソースすべてに上書き(削除→再作成)がかかっていました。
更新されるべきものだけ上書きされるようなコマンドを捜索中ですが、一旦は、sam sync --no watchにて、手動でまとめてリソース作成したほうが、コスト的にも良さそうです。

【小技】作成したリソースの確認

sam deployで作成したリソースは sam list endpoints で確認できます。
API GatewayのURLとメソッドは、CloudEndpointおよびMethods項目で確認できます。

$ sam list endpoints --output json

# lambdaとapi gatewayのリソースが表示される。
# lambdaはインターネットへの入出口がないので、CloudEndpointおよびMethods項目が「-」となる
[
  {
    "LogicalResourceId": "HelloWorldFunction",
    "CloudEndpoint": "-",
    "Methods": "-"
  },
  {
    "LogicalResourceId": "ServerlessRestApi",
    "CloudEndpoint": ["https://*****.execute-api.ap-northeast-1.amazonaws.com/Prod"],
    "Methods": ["/hello['get']"]
  }
]

【小技】クラウド上のリソース削除

SAMプロジェクトで作成したリソースをsam deleteで一斉削除できます。

$ sam delete

Are you sure you want to delete the stack sam-app in the region ap-northeast-1 ? [y/N]: y
Deleted successfully

コマンドまとめ

コマンド 用途
sam init SAMプロジェクト作成
sam build SAMプロジェクトのビルド
sam deploy デプロイしてクラウド上にリソース作成
sam list endpoints 作成したリソースの確認
sam local invoke ローカルでLambda関数を疑似的に実行
sam local start-api ローカルでAPIを疑似的に呼び出し
sam sync ローカルファイルの更新をリソースに反映
sam delete 作成したリソースを削除

おわりに

今回は、SAMを使用したローカルコンテナでのデプロイ前テストや、便利な小技・トラブルシューティングを紹介しました。
特に sam local コマンドを使ったローカルテストは、コスト削減や開発効率化に大きく貢献します。
前回のブログと合わせて、SAMを使った効率的な開発フローの参考になれば幸いです。

それでは。