Swagger codegenで作ったFlaskアプリをAWS Lambdaにデプロイして使う
WEB+DB PRESS Vol.105 にあった記事にあった、FlaskアプリをAWS Lambdaにデプロイして使う方法を少しアレンジし、Swagger codegenで作ったFlaskアプリをデプロイしてみたので、手順のメモ。
手順メモ
Swagger codegen
swagger editorでAPI定義を書き、サーバコードをダウンロード。(Generate Server -> python-flask)
ちなみにこのとき、python-flaskをクリックしても全く反応しないんだけど、裏でHTTPS接続でエラーが出てるみたいで、ChromeならF12とかでデバッグログ出して、エラーになってるURLへ直接ブラウザで接続したらダウンロードできた。
ローカルでコードの編集
フォルダ構成
mylambda/ ├── functions │ └── mylambda │ └── main.py # Lambdaのエントリポイントを記述するファイル ├── project.json # Apexの設定ファイル ├── requirements.txt # Lambdaのコンテナにデプロイするパッケージのインストール用 └── src └── swagger_server # codegenの中のディレクトリをコピー
mylambdaのmain.pyには、swagger_server内の__main__.py
のほぼコピペの内容を記載する。
import sys import pathlib # 記事の通り lib_path = str(pathlib.Path("./lib").absolute()) sys.path.append(lib_path) import awsgi # swaggerのコードをほぼコピペ # パスの階層とかをちょっといじってあげる import connexion from swagger_server import encoder def lambda_handler(event, context): app = connexion.App(__name__, specification_dir='./lib/swagger_server/swagger/') app.app.json_encoder = encoder.JSONEncoder app.add_api('swagger.yaml', arguments={'title': 'MyAPI'}) return awsgi.response(app, event, context)
Apexの導入
公式の手順に沿って実施。
Apexの設定(project.json)の記述
{ "name": "mylambda", "description": "", "memory": 128, "timeout": 5, "role": "arn:aws:iam::XXXXXXXXXXXX:role/mylambda_lambda_function", "environment": {}, "runtime": "python3.6", "handler": "main.lambda_handler", "hooks": { "build": "mkdir ./lib && cp -r ../../src/* ./lib && pip install -r ../../requirements.txt -t ./lib" } }
- runtimeをpython3.6にする
- hooksにて、デプロイ時に事前実行するコマンドを定義する。ここではWebDBの記事同様の手順で以下を行うようにする。
- srcの中身をfunctions/mylambda/libへコピー
- functions/mylambda/libへpipパッケージをインストール
requirements.txtの記述
Flask, aws-wsgi, connexionが必須。それ以外は自分のアプリに合わせて追加する。
DynamoDB使うならboto3とか。
Apexを使ってデプロイ
project.jsonのあるディレクトリにて、コマンドapex deploy
を実行。
- awscliをインストール済みであること
- 適切な権限を持ったユーザ・ロールのAPIアクセスキーを環境変数に設定済みであること(適切な権限は状況によるっぽいが、IAM作成権限が必要だったので、結構強い権限が要ると思う)
API Gatewayの設定
メソッドの作成にて、図のようにプロキシリソースにチェックを入れれば、自動的にリクエストをスルーパスする設定になる。
次の画面でLambdaも指定してあげれば完了。
API デプロイ
APIGatewayにてAPIのデプロイをする。
ステージ名はswagger定義のパスには入らない。
swaggerのパス定義に/hogeapi/fuga とかしたら、https://xxxxx.amazonaws.com/[ステージ名]/hogeapi/fugaでアクセスできる。
デバッグしたいとき
上記でうまくいったんだけど、途中うまくいかなかったときにデバッグで便利だったことのメモ。
Lambdaのテスト
Lambdaの関数画面上部のテストでは、作成時にひな型を選べる。
この中からAPIGateway AWS Proxyのひな型を選ぶと、APIGatewayからLambda統合で呼び出すときのリクエストが再現できる。
パスとhttpmethodあたりだけ書き換えてあげればいい。
Cloudwatch
結果的にはできなかったんだけど、たぶんAPI Gatewayの設定でCloudWatchログを吐くようにしてあげればリクエスト時のエラーを確認できる。気がする。
その他
- Apexのフォルダ構成とか、swaggerのmainをコピペとか、APIGatewayの設定ポチポチとか、ちょっとめんどい。
Zappa
その後、Zappaとかいう素敵感のあるものを見つけた!
- ZappaはFlaskコードをそのままAPIGateway含めてサーバレス化(Lambdaデプロイ+APIGateway作成)をしてくれるすごいやつだった。
- 使い方は、試すくらいなら公式チュートリアルでいけるし、ググるといくらか記事がある。
- デプロイ時、/に対するヘルスチェックが入り、失敗するとデプロイ中断されるので、Swagger codegenしたものをデプロイするときは、/に対するGETに正常なレスポンスを返すように設計されている必要がありそう。(未検証)
以上。