この記事の目的
Python + FlaskのアプリをZappaを使ってAWS Lambdaにデプロイして、動作確認まで行います。 macでの環境の構築をメインに、丁寧に書いていきます。
Zappaとは
GitHub:Zappa
ZappaはコマンドラインでPythonのWSGIアプリケーションをデプロイできます。 AWSではLambdaに、また、他ののクラウドにも対応しています。
Lambdaでは直接コードを書く場合と、コードとライブラリをまとめたZIPファイルをアップロードしてデプロイします。
Zappaではvirtualenv
の仮想環境をZIPファイルにまとめて、デプロイします。ZIPの作成も自動的に行なってくれるのでとても簡単です。
自分でZIPファイルにまとめてデプロイも可能です。 zipコマンドについてはこちら。
デプロイの様子 : Zappaより
必要な環境さえ整えれば、GIFの通り簡単にAWSにコードをデプロイすることができます。
日本語の記事では、zappa で hello world するまでが参考になります。CentOS7で確認されていますので、Redhat系の方はこちらの手順で進めて見てください。公式からもリンクされており、公認みたいです。
公式を翻訳しているサイトZappa – サーバーレスPythonもあります。応援しています‼️
環境
- macOS High Sierra
- Python3.6.5
- pyenv 1.2.3
流れ
- pyenvとpyvirtualenvのインストール
- Python3.6の準備
- AWSのIAMの設定
- デプロイする仮想環境の構築
- アプリケーションの用意
- Zappaのインストールとデプロイ
手順
1. pyenvとpyvirtualenvのインストール
まずは、仮想環境を用意しましょう。
macではパッケージマネージャーのHome Brew
を使ってツールをインストールします。Home Brew
がまだない方は、こちらのスクリプトをコピーして、実行してください。
Home Brew
をインストールできたら下記の手順でpyenvとpyvirtualenvのインストールを進めます。
$ brew install pyenv
$ brew update && brew upgrade pyenv
pyenv 1.2.1 -> 1.2.3
$ brew install pyenv-virtualenv
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
echo ...
でpyenvをログイン時に起動するよう書き込み、exec ...
で即時起動しています。(たぶん。。。)
2. Python3.6の準備
続いて、macの環境をPython3.6にしておきましょう。 macにはデフォルトで2.7が入っています。変えたくない方や、他のバージョンを使っている方は飛ばしてください。
$ pyenv install 3.6.5
# 全体に反映
$ pyenv global 3.6.5
$ python --version
Python 3.6.5
python3.6が確認できたら、pipもアップグレードしておきます。aws cli
をインストールするのに使います。
$ pip -V
pip 9.0.3 from /Users/{user}/.pyenv/versions/3.6.5/lib/python3.6/site-packages (python 3.6)
$ pip install -U pip
Successfully installed pip-10.0.1
3. AWSのIAMの設定
AWSにデプロイするためには、アクセスできるユーザとサービスの操作を許可するIAMの設定が必要です。
コンソールからデプロイ用のユーザを作成し、アクセスキーとシークレットキーを保管してください。 IAMの設定でユーザに操作の許可を与えてください。Lambda、S3、API GatewayのFullaccessは必要。その他、利用するサービスの権限を与えて下さい。
Minimum AWS policies for example. こちらにpermission policieの例が載っています。
ターミナルに戻って、キーの設定を行います。
$ pip install awscli
$ aws configure
AWS Access Key ID [********************]:
AWS Secret Access Key [********************]:
Default region name [ap-northeast-1]:
Default output format [json]:
aws configure
でアクセスキーなどを聞かれるので、打ち込んであげてください。 regionは東京にしました。
4. デプロイする仮想環境の構築
Lambdaには仮想環境ごとライブラリをまとめてデプロイします。 フォルダごとに仮想環境を用意しておくと何かと便利なので、ローカル環境を作成します。
$ pyenv virtualenv 3.6.5 bar
$ mkdir foo
$ cd foo
$ pyenv local bar
(bar) $ となっていれば成功。
foo
というフォルダを用意して、そこにローカル環境bar
を作成しています。
fooとローカル環境には適当な名前をつけて下さい。
※注意 仮想環境の名前はZappaのプロジェクト名と同じものを使用しないで下さい。エラーが起こり得ます。
ここまでは、macで別のバージョンのpythonを使うとき便利です。
ローカル環境もpipを最新にしておきます。
$ pip install -U pip
Successfully installed pip-10.0.1
5. アプリケーションの用意
Flaskを使ってhello from Flask!
を返す簡単なアプリを作成します。
仮想環境を用意したディレクトリfooに、app.py
を作成します。
foo/app.py
from flask import Flask
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def lambda_handler(event=None, context=None):
return 'hello from Flask!'
if __name__ == '__main__':
app.run()
fooに移動して、ライブラリをインストールして確かめて見ましょう。
$ cd foo
$ pip install flask
Successfully installed Flask-1.0.2 Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 itsdangerous-0.24
$ pip freeze
click==6.7
Flask==1.0.2
itsdangerous==0.24
Jinja2==2.10
MarkupSafe==1.0
Werkzeug==0.14.1
$ python app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
http://127.0.0.1:5000/をブラウザで開いて確認して見てください。
6. Zappaのインストールとデプロイ
とうとう、デプロイするところまできました。 まずは、Zappaをインストールして設定を行います。
$ pip install zappa
$ zappa init
███████╗ █████╗ ██████╗ ██████╗ █████╗
╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗
███╔╝ ███████║██████╔╝██████╔╝███████║
███╔╝ ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║
███████╗██║ ██║██║ ██║ ██║ ██║
╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝
Welcome to Zappa!
設定は全てEnter
を押してデフォルトにすると以下のzappa_settings.json
が作成されます。
フォルダ名がプロジェクト名になっています。
Okay, here's your zappa_settings.json:
{
"dev": {
"app_function": "app.app",
"aws_region": "ap-northeast-1",
"profile_name": "default",
"project_name": "foo",
"runtime": "python3.6",
"s3_bucket": "zappa-9jex9436c"
}
}
Does this look okay? (default 'y') [y/n]: y
$ ls
app.py zappa_settings.json
※注意(再掲) 仮想環境の名前はZappaのプロジェクト名と同じものを使用しないで下さい。エラーが起こり得ます。
注意点として、実行ファイルの名前を合わせる必要があります。 zappa_setting.jsonの"app_function"を"{実行するファイル名}.app"として下さい。hello.pyを実行する場合は次のようにします。
"app_function": "hello.app",
デプロイします。
$ zappa deploy
Deployment complete!: https://81dc4kiste.execute-api.ap-northeast-1.amazonaws.com/dev
成功すると、API GatewayのURLが表示されます。
AWSのコンソールからLambdaを確認するとfoo-dev
という関数が作られていました。
※私の環境ではpermission policieにDynamoDBなども含めているので、Lambdaからアクセスできるようになっています。
アップデートもしてみましょう。
せっかくなので、URLで応答を変えるようにします。
hello_name()
の関数を追加しました。
foo/app.py
from flask import Flask
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def lambda_handler(event=None, context=None):
return 'hello from Flask!'
@app.route('/<name>', methods=['GET', 'POST'])
def hello_name(name):
return 'hello ' + name
if __name__ == '__main__':
app.run()
アップデートします。
$ zappa update
URLの末尾に文字を入れてください。
その他、ログを監視するtail
や前のバージョンにロールバックするrollback
など便利なコマンドがあります。
zappa -h
で確認してください。
zappaの導入手順は以上となります。
同様のライブラリ
こちらはAWSのためのAmazon製のサーバレスマイクロフレームワーク。LambdaとAPI Gatewayのデプロイができるようです。
Zappaとの比較はこちらの記事が参考になりました。 Python サーバーレスフレームワークの比較 - Zappa vs Chalice
終わりに
Pythonでサーバレスな開発を行うなら、zappaがとても便利だと思います。 ただ、日本語の情報が少ないので、躓いたとき辛いです。。。 少しでも参考になれば、幸いです。
サーバレスアーキテクチャを勉強される方は、こちらの本がおすすめです。
動画シェアサイトをAWS Lambda, S3を使って実際に構築する手順が載っています。 その中で、どのようにLambdaを構成したら良いか大変参考になりました。また、DynamoDBとAuth0も詳しく書かれています。