概要
AWS SAM、FastAPI、Mangum を使って API 開発をやってみる
上記を実施。
チュートリアルはcloud9で行われていたが、次の職場ではVScode上からSSHでリモートのEC2コンテナにexecして開発するとのことなので、dockerで再現してやってみた。
以下やってみてのエトセトラ。
チュートリアル通りにやって躓いたところ
sam buildで失敗する
以下で解決
- チュートリアルで示されているDockerfileのimageが取得できるか
docker pull public.ecr.aws/lambda/python:3.9
- 取得できた場合、そのimageでlocalビルドできるか?
docker build -t test-lambda ./hello_world
- Buildできる場合、特に依存関係等は複雑に設定をしていないのでDockerのキャッシュ周りが怪しい
- 全部削除してみる
docker builder prune -a
- 全部削除してみる
- キャッシュに依存しないでもう一度sam buildしてみる
sam build --cached
sam build --no-cache
sam deploy後、エンドポイントを叩くと{"message": "Internal server error"}%
となる
どうやらLambdaのコンテナイメージでアーキテクチャを明示しないといけないらしい
Macなのでarm64で指定しておく
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
# Lambda関数をDockerで作成
Properties:
PackageType: Image
# コンテナイメージのアーキテクチャを指定しておかないとエラーになるので指定
Architectures:
- arm64
tests/integration/test_api_gateway.py
のpytestが失敗する
cloud9ではなく、localでコンテナ化したためAWS認証情報が足りないのでaws configureする。
実際は systems manager等から引っ張り出すか、profileにするかする
リージョンとスタック名の設定もしておく(スタック名は本来なら環境変数にしておく)
export AWS_SAM_STACK_NAME=buildersflash-aws-sam-app
export AWS_DEFAULT_REGION=ap-northeast-1
TIPS: CLIは後からいれるのは面倒なのであらかじめインストールしておくようにDockerfileに仕込む
# イメージの設定、Macなのでarm64としておく
FROM --platform=linux/arm64 base as stage-arm64
# CLIとSessionManagerとSAM CLIのインストール
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip" && \
unzip awscliv2.zip && \
./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --update && \
rm -rf awscliv2.zip
RUN curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_arm64/session-manager-plugin.deb" -o "session-manager-plugin.deb" && \
apt-get install -y ./session-manager-plugin.deb && \
rm -f session-manager-plugin.deb
RUN curl -LO "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-arm64.zip" && \
unzip aws-sam-cli-linux-arm64.zip -d sam-installation && \
./sam-installation/install && \
rm -rf aws-sam-cli-linux-arm64.zip sam-installation
SAMのローカル実行について
ローカルでのテストはコンテナ外でもできる。
(実際にdeployしたAPIを叩くなら、当然だけどexecして中で叩かないとダメ)
-
sam local start-lambda
-
上記を実行した上で別のターミナルで以下を入力してみる
aws lambda invoke --function-name "HelloWorldFunction" --endpoint-url "[http://127.0.0.1:3001](http://127.0.0.1:3001/)" --payload file://events/event.json --cli-binary-format raw-in-base64-out response.json
-
--function-name
設定した関数名 -
--endpoint-url
関数(API)のエンドポイント -
--payload
関数をmockをするためのパラメータが入っているファイルを指定 -
--cli-binary-format raw-in-base64-out response.json
出力内容
-
-
あとは
cat response.json
で内容を見れる(rm response.json
で消しておくのも忘れずに)
-
-
sam local start-api
- start-lambdaはLambda関数自体のエミュレータだが、こちらはAPIGatewayのエミュレータ
- 定義された API エンドポイント(
template.yaml
に記載)をローカルで起動し、それにアクセスし、それを通じてLambda関数をキックする - コマンド実行後、
curl -X GET エンドポイント
でAPIを叩いて実行結果を見れる