コラム

2021.08.31

【テックコラム】Zappaで最速サーバレスコンピューティング

● はじめに


皆さんは AWS Lambda と Amazon API Gateway は利用しているでしょうか。
もし それらを利用し、且つ python で 開発するのであれば Zappa がお勧めですので、今回ご紹介させていただきます。

● Zappa とは


Zappaとは、AWS Lambda と Amazon API gateway 等のサービスを利用して、Web アプリケーションを構築するサーバレスフレームワークです。

https://github.com/zappa/Zappa

通常の Lambda と API gateway の組み合わせでは、下記の様な(お手軽でない)課題があります。

  • Web アプリであっても使い慣れた Flask 等の WGSI アプリケーションではなく Lambda 用にコーディングしなければならない
  • 標準でサポートされていないライブラリを使用する際は zip ファイルでデプロイパッケージを作成し、アップロードする必要がある(Lambda では docker image がサポートされていますが、イメージの管理があり手間としては変わらない)
  • ログが手軽に参照できない
  • 必要な設定や操作が多く、それらを CLI で完結することが難しい

Zappa ではこれらの課題を上手にラッピングし、手軽なアプリケーション開発を支援します。
同様のフレームワークでは Serverless Framework や chalice 等がありますが、実現できる機能とお手軽さにおいて Zappa が優れていると言えますね。

● Zappa で出来ること


Zappa は非常に多機能ですが、下記に主要な機能を紹介します。

【アプリケーション実行機能】

  • WSGI アプリケーションの実行
  • CloudWatch Events によるスケジュール実行
  • 非同期タスク実行

【開発、運用のサポート機能】

  • CloudWatch Logs ログの tail 
  • 開発、ステージング、プロダクションといったステージごとの設定とデプロイ
  • 任意の世代へロールバック
  • 任意の関数の手動実行
  • ACM や Let’s Encrypt などを利用した独自ドメイン
  • ACM への証明書発行リクエスト
  • API Gateway のアクセスポリシー設定
  • Keep warm でレスポンス速度の維持 

これらの操作を単一のコマンドから実行できます。

またデプロイ時に IAM Role や Lambda イメージ用 S3 の自動作成も可能です。
(自動作成せず既存の IAM Role や S3 Bucket の指定も可能)

● python 仮想環境の作成と zappa のインストール


Zappa では python 仮想環境が必須なので、venv モジュールで作成した環境へインストールします。

以降の作業環境は Ubuntu 20.04 LTS を使用しました。また AWS CLI の設定が完了している必要があります。

$ python3 -m venv zappa_env
$ . zappa_env/bin/activate
$ pip install zappa==0.53.0 && pip install troposphere==2.7.1
$ pip install werkzeug==2.0.1 flask==2.0.1

注意としては、この記事の執筆時ではライブラリのバージョンによってエラーとなる点です。
対策として上記のようにバージョンを指定しています。
また Zappa の依存関係で要求される werkzeug のバージョンは 1.0 未満ですが、2.0.1 でも問題ないようです。

zappa コマンドを実行する環境ですが、Lambda のサポートバージョンに倣い python 3.6 ~ 3.8 となっています。
アドホックですが 3.9 を許可する場合は、python 仮想環境の site-packages/zappa/__init__.py へ下記の様にバージョンを追加します。

SUPPORTED_VERSIONS = [(3, 6), (3, 7), (3, 8), (3, 9)]

最近 Lambda でも 3.9 がサポートされましたので、オフィシャルで対応して貰えると有難いですね。

● アプリケーションの初期化


アプリケーションのディレクトリを作成し、その中で 初期化コマンドを実行します。

$ mkdir my_app
$ cd my_app
$ zappa init

Welcome to Zappa
███████╗ █████╗ ██████╗ ██████╗  █████╗
╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗
  ███╔╝ ███████║██████╔╝██████╔╝███████║
 ███╔╝  ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║
███████╗██║  ██║██║     ██║     ██║  ██║
╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝     ╚═╝  ╚═╝
(以下略)

いくつか入力を求められますが、そのままエンターを押していきます。
一点、下記の入力には my_app.app を入力します。

Where is your app's function?: my_app.app

初期化が完了すると、zappa_settings.json が作成されます。
デフォルトのステージ名は dev ですので、以降はこのステージ名を使用します。

● hello world アプリケーションのデプロイ


下記の内容で my_app.py を作成します。

from flask import Flask

app = Flask(__name__)

@app.route('/')
def root():
    return 'Hello world'

【デプロイ】

zappa deploy でデプロイを行います。
以降、コマンド実行時は環境名(今回は dev)を必ず引数に与えます。

$ zappa deploy dev
Calling deploy for stage dev..
Creating my-app-dev-ZappaLambdaExecutionRole IAM Role..
Creating zappa-permissions policy on my-app-dev-ZappaLambdaExecutionRole IAM Role.
(中略)
Deploying API Gateway..
Deployment complete!: https://59inf8jsy0.execute-api.ap-northeast-1.amazonaws.com/dev

API Gateway が作成され、URL が払い出されました。(59inf8jsy0 の部分はデプロイ毎に変化します)
ではブラウザで URL にアクセスしてみましょう。Hello World が表示されれば OK です。

Lambda と API Gateway を個々に設定する場合と比べて、圧倒的に素早くデプロイが完了できました。

【状態の確認】

zappa status で現在のデプロイ状態を確認できます。

$ zappa tail dev
Status for my-app-dev:
        Lambda Versions:      2
        Lambda Name:          my-app-dev
        Lambda ARN:           arn:aws:lambda:ap-northeast-1:529488690984:function:my-app-dev
        Lambda Role ARN:      arn:aws:iam::529488690984:role/my-app-dev-ZappaLambdaExecutionRole
        Lambda Code Size:     27828157
        Lambda Version:       $LATEST
        Lambda Last Modified: 2021-08-24T22:46:49.581+0000
        Lambda Memory Size:   512
        Lambda Timeout:       30
        Lambda Handler:       handler.lambda_handler
        Lambda Runtime:       python3.8
        Lambda VPC ID:        None
        Invocations (24h):    3
        Errors (24h):         0
        Error Rate (24h):     0.00%
        API Gateway URL:      https://59inf8jsy0.execute-api.ap-northeast-1.amazonaws.com/dev
        Domain URL:           None Supplied
        Num. Event Rules:     1
        Event Rule Name:      my-app-dev-zappa-keep-warm-handler.keep_warm_callback
        Event Rule Schedule:  rate(4 minutes)
        Event Rule State:     Enabled
        Event Rule ARN:       arn:aws:events:ap-northeast-1:529488690984:rule/my-app-dev-zappa-keep-warm-handler.keep_warm_callback

デフォルトでは 4 分ごとに Keep warm が設定されます。
Event Role 周りで設定されていることが分かりますね。

【ログの確認】

ログは zappa tail dev コマンドで確認できます。CloudWatch Logs が整形されて表示されます。
tail コマンドのように、ログが発生する度に表示が更新されます。

終了するには Ctrl と C キーを同時押しします。

● アプリケーションの更新と終了


【アプリケーションの更新】

アプリケーションを更新する際は、zappa update コマンドを使用します。(zappa deploy ではありませんので注意)

$ zappa update dev

もし正常に更新できなかった場合でも安全にロールバックが行われ、以前の状態が維持されていますので安心です。

【アプリケーションの終了】

終了は zappa undeply コマンドです。

$ zappa undeploy dev
Calling undeploy for stage dev..
Are you sure you want to undeploy? [y/n] y
(確認が施されるので、y を入力します。)

Deleting API Gateway..
Waiting for stack my-app-dev to be deleted..
Unscheduling..
Unscheduled my-app-dev-zappa-keep-warm-handler.keep_warm_callback.
Deleting Lambda function..
Done!

● 自動生成されたリソースの削除


【IAM Role】

zappa_settings.json で IAM Role を明示的に指定しない場合は自動生成されているので、不要であれば削除します。
zappa deploy 時に下記のようなメッセージが出力されるので、これを削除します。

Creating my-app-dev-ZappaLambdaExecutionRole IAM Role..

【S3】

zappa_settings.json の “s3_bucket”: で定義されている bucket を削除します。

● 最後に


今回は Zappa の基本的な機能とデプロイについて紹介いたしました。 

Zappa は Web アプリケーションの開発・デプロイの手軽さと、本格的なサービス構築に耐えうる機能の充実の両方を兼ね備えている優れたフレームワークです。
オフィシャルページには今回紹介しきれなかった機能が解説されていますので、他の機能も試してみてはいかがでしょうか。

弊社ではデータ活用のためのシステム開発支援も行っております。
ご興味がございましたら是非お問い合わせください。

本件に関するお問い合わせは下記にて承ります。
株式会社DataCurrent
info@datacurrent.co.jp