zappa を利用して
Flaskアプリのデプロイを行います…が
localhost上のMySQLに接続する実装だったためDBへのアクセスはできません。
環境変数やParameterStore, SecretsManagerを利用してDBのURLを切り替える必要があります。
VPCの勉強終わったら更新します…
AWS Cliの準備
aws configure
APIキーを取得し、aws cliが使用できる状態にします。
zappaインストール
(venv) $ pip install zappa
Flaskプロジェクトにzappaをインストールします。
zappa初期化
全部デフォルトでOKです。
(venv) $ zappa init
███████╗ █████╗ ██████╗ ██████╗ █████╗
╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗
███╔╝ ███████║██████╔╝██████╔╝███████║
███╔╝ ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║
███████╗██║ ██║██║ ██║ ██║ ██║
╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝
Welcome to Zappa!
Zappa is a system for running server-less Python web applications on AWS Lambda and AWS API Gateway.
This `init` command will help you create and configure your new Zappa deployment.
Let's get started!
Your Zappa configuration can support multiple production stages, like 'dev', 'staging', and 'production'.
What do you want to call this environment (default 'dev'):
AWS Lambda and API Gateway are only available in certain regions. Let's check to make sure you have a profile set up in one that will work.
Okay, using profile default!
Your Zappa deployments will need to be uploaded to a private S3 bucket.
If you don't have a bucket yet, we'll create one for you too.
What do you want to call your bucket? (default 'zappa-k7rlsxrxg'):
It looks like this is a Flask application.
What's the modular path to your app's function?
This will likely be something like 'your_module.app'.
We discovered: app.app
Where is your app's function? (default 'app.app'):
You can optionally deploy to all available regions in order to provide fast global service.
If you are using Zappa for the first time, you probably don't want to do this!
Would you like to deploy this application globally? (default 'n') [y/n/(p)rimary]:
Okay, here's your zappa_settings.json:
{
"dev": {
"app_function": "app.app",
"aws_region": "ap-northeast-1",
"profile_name": "default",
"project_name": "flask-sample",
"runtime": "python3.9",
"s3_bucket": "zappa-k7rlsxrxg"
}
}
Does this look okay? (default 'y') [y/n]:
Done! Now you can deploy your Zappa application by executing:
$ zappa deploy dev
After that, you can update your application code with:
$ zappa update dev
To learn more, check out our project page on GitHub here: https://github.com/Zappa/Zappa
and stop by our Slack channel here: https://zappateam.slack.com
Enjoy!,
~ Team Zappa!
zappa_settings.json
が作成され、
デフォルトではdev
という名前で環境が作成されます。
'dev', 'staging', 'production'など、複数の環境を切り替えてデプロイできます。
zappa用ロールを設定。APIGatewayにCognitoを追加
Cognitoの設定は任意です。
{
"dev": {
"app_function": "app.app",
"aws_region": "ap-northeast-1",
"profile_name": "default",
"project_name": "flask-example",
"runtime": "python3.9",
"s3_bucket": "zappa-7fq7rplg7",
// ロールの設定
// https://github.com/zappa/Zappa#using-custom-aws-iam-roles-and-policies
"manage_roles": false,
"role_name": "flask-example-dev-ZappaLambdaExecutionRole",
// Cognitoの設定
// https://github.com/zappa/Zappa#cognito-user-pool-authorizer
"authorizer": {
"type": "COGNITO_USER_POOLS",
"provider_arns": [
"arn:xxx"
],
"token_header": "Authorization"
}
}
}
"manage_roles": true
にするとzappa用ロールを自動で作成します。
私のaws cliのユーザーにはロール作成権限がなかったせいかエラーになりました。
zappa用IAMユーザーのポリシー
ネット上の記事を参考にしました。
必要以上の権限が付与されているかもしれませんが、私はこれでデプロイまでできました。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:AttachNetworkInterface",
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:DescribeInstances",
"ec2:DescribeNetworkInterfaces",
"ec2:DetachNetworkInterface",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:ResetNetworkInterfaceAttribute"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"kinesis:*"
],
"Resource": "arn:aws:kinesis:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"sns:*"
],
"Resource": "arn:aws:sns:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"sqs:*"
],
"Resource": "arn:aws:sqs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"dynamodb:*"
],
"Resource": "arn:aws:dynamodb:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"route53:*"
],
"Resource": "*"
}
]
}
デプロイ実行
(venv) $ zappa deploy dev
Calling deploy for stage dev..
Downloading and installing dependencies..
- pyrsistent==0.18.1: Downloading
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 116k/116k [00:00<00:00, 1.13MB/s]
- markupsafe==2.0.1: Downloading
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 30.6k/30.6k [00:00<00:00, 2.31MB/s]
- greenlet==1.1.2: Downloading
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 169k/169k [00:00<00:00, 1.42MB/s]
Packaging project as zip.
Uploading flask-example-dev-1643965354.zip (18.4MiB)..
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 19.3M/19.3M [00:48<00:00, 398kB/s]
Waiting for lambda function [flask-example-dev] to become active...
Scheduling..
Scheduled flask-example-dev-zappa-keep-warm-handler.keep_warm_callback with expression rate(4 minutes)!
Uploading flask-example-dev-template-1643965474.json (1.6KiB)..
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.65k/1.65k [00:00<00:00, 11.7kB/s]
Waiting for stack flask-example-dev to create (this can take a bit)..
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4/4 [00:16<00:00, 4.02s/res]
Deploying API Gateway..
Waiting for lambda function [flask-example-dev] to be updated...
Deployment complete!: https://xxxxx.ap-northeast-1.amazonaws.com/dev
これでデプロイ完了です。
Deployment complete!: https://xxxxx.ap-northeast-1.amazonaws.com/dev
にあるURLをブラウザで開けばSwaggerUI画面が開きます。
何が行われたのか?
zappa deploy dev
の裏でなにが起こっているのか?
その辺の情報はzappaを見てもあまり書いていないようなので
デプロイするまでに奮闘した経験から書かせてもらいます。
-
zappa deploy dev
を実行 -
zappa_settings.json
からCloudFormationテンプレートを作成 - テンプレートとFlaskアプリをzipファイルにまとめる
- zipファイルをzappa用ロールを利用してs3にアップロード
- CloudFormationテンプレートからAPI Gateway, Lambdaなどを作成
という感じのようです。
Flaskアプリは基本的にport: 5000でリクエストを待ち受けるのにどうやってポート変換しているんだろう…。
CloudFormationの知見が不足しているのでそれは後々追っていくことにします。
FlaskだけではなくDjangoやDockerコンテナもzappaを使用してデプロイできます。
zappa invoke dev "app.db.upgrade"
のようなinvokeコマンドを利用するとデプロイしたアプリの
関数を実行でき、DBのマイグレーションもこれで実行できました。
その他zappaコマンド
zappa undeploy # デプロイしたアプリをAWSから削除
zappa update dev # デプロイ済みのアプリを更新
zappa tail # ログの表示。デプロイエラー時の調査などに。CloudWatchのログを表示しているだけ?