ChaliceとSAMのLambdaのデプロイ速度を比べてみた

AWS ChaliceとAWS SAMのデプロイ速度を比較してChaliceのデプロイ速度の速さを確認します。
2020.03.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CX事業本部東京の佐藤智樹です。

今回はSAMとChaliceのLambdaのデプロイ速度を比べてみたいと思います。以前Chaliceのハンズオンに参加した際にSAMで開発していた時と比べてデプロイ速度がかなり早くて驚いたので、実際に比較してみたいと思い記事にしました。SAMはS3やDynamoDBなど幅広くカバーするサービスで、ChaliceはWebAPI作成に特化したサービスなので使用用途は異なりますのでどちらかが必ず良い!というわけではないのでその点はご理解ください。

今回の記事では1度目のデプロイでは対話形でのデプロイとなるため測りづらく、ポリシーやロールの作成にSAMとChaliceで差分があるので2回目以降のデプロイでLambdaのコードを修正して比較します。結果だけみたい方は速度比較に飛んでください。

実行環境は以下の通りです。

項目名 バージョン
OS Mac OS Catalina 10.15.3
SAM 0.44.0
Chalice 1.13.0
python 3.6.5
zsh 5.7.1

目次

SAMとは

以下公式よりの引用です。

AWS サーバーレスアプリケーションモデル (SAM、Serverless Application Model) は、サーバーレスアプリケーション構築用のオープンソースフレームワークです。迅速に記述可能な構文で関数、API、データベース、イベントソースマッピングを表現できます。リソースごとにわずか数行で、任意のアプリケーションを定義して YAML を使用してモデリングできます。デプロイ中、SAM が SAM 構文を AWS CloudFormation 構文に変換および拡張することで、サーバーレスアプリケーションの構築を高速化することができます。

AWS サーバーレスアプリケーションモデル - アマゾン ウェブ サービス

CloudFormationをサーバレスアプリケーションの構築にさらに特化させLambdaやロールなどを簡易にyamlで書けて、ローカルでのテスト実行環境の構築やリポジトリの外部公開などもできます。SAMではLambdaやAPI Gateway、S3、DynamoDBなどが構築できます。(完全に余談ですがいつの間にかトップページのリスが宇宙空間にいて、前はかわいいサイズだったのに人型になっていてビビりました)

Chaliceとは

ChaliceはAPI GatewayとLambdaで構築されるAPIを高速に作るためのサービスです。言語はpythonのみですが、SAMなどで構築するほどでもないが高速にWebAPIの開発をガンガン回したい時に役立つサービスです。構築自体はyaml形式ではなくCDKのようにプログラム言語で記述します。

デプロイまでの準備(SAM)

SAMの初回デプロイ時は、対話式の設定になるので初回設定は行った後にLambdaを修正したあとの反映速度で比較します。なので一旦は普通にSAMのデプロイまでの作業を行います。

SAMでプロジェクトを生成

$ sam --version
SAM CLI, version 0.44.0
$ sam init --runtime python3.6 --dependency-manager pip --app-template hello-world --name sam-app
$ tree
.
└── sam-app
    ├── README.md
    ├── events
    │   └── event.json
    ├── hello_world
    │   ├── __init__.py
    │   ├── app.py
    │   └── requirements.txt
    ├── template.yaml
    └── tests
        └── unit
            ├── __init__.py
            └── test_handler.py

SAMでデプロイ

$ cd sam-app
$ sam build
$ sam deploy --guided

Configuring SAM deploy
======================

	Looking for samconfig.toml :  Not found

	Setting default arguments for 'sam deploy'
	=========================================
	Stack Name [sam-app]: 
	AWS Region [us-east-1]: ap-northeast-1
	#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
	Confirm changes before deploy [y/N]: y
	#SAM needs permission to be able to create roles to connect to the resources in your template
	Allow SAM CLI IAM role creation [Y/n]: 
	Save arguments to samconfig.toml [Y/n]: 
(中略)
Successfully created/updated stack - sam-app in ap-northeast-1
$ curl  https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ 
{"message": "hello world"}

上記でSAMのデプロイは一旦完了です。

デプロイまでの準備(Chalice)

Chaliceのプロジェクト作成

$ chalice --version
chalice 1.13.0, python 3.6.5, darwin 19.3.0
$ chalice new-project chalice-test
$ tree
.
└── chalice-test
    ├── app.py
    └── requirements.txt
$ cd chalice-test 
$ chalice deploy
Creating deployment package.
Creating IAM role: chalice-test-dev
Creating lambda function: chalice-test-dev
Creating Rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:chalice-test-dev
  - Rest API URL: https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/api/
$ curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/api/
{"hello":"world"}

上記でChaliceのデプロイも完了です。

速度比較

それぞれLambdaのレスポンスを書き換えて実行速度を比較します。ここで実行速度はtimeコマンドのreal値で比較し、デプロイが完了してレスポンスが返ってくるまでの時間とします。まずコードを以下のように変更します

SAM(レスポンスbodyのxxxの部分を修正してデプロイ×3回)

hello_world/app.py

import json

# import requests


def lambda_handler(event, context):
    """Sample pure Lambda function
    (コメント中略)
    """

    # try:
    #     ip = requests.get("http://checkip.amazonaws.com/")
    # except requests.RequestException as e:
    #     # Send some context about this error to Lambda Logs
    #     print(e)

    #     raise e

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world xxx",
            # "location": ip.text.replace("\n", "")
        }),
    }
$ \time sam build ;\time sam deploy --no-execute-changeset
SAMの実行結果
回数 sam build実行時間(秒) sam deploy実行時間(秒) 合計(秒)
1回目 3.18 18.61 21.79
2回目 4.05 19.89 23.94
3回目 3.19 19.80 22.99

Chalice(レスポンスbodyのxxxの部分を修正してデプロイ×3回)

app.py

from chalice import Chalice

app = Chalice(app_name='chalice-test')


@app.route('/')
def index():
    return {'hello': 'world xxx'}
$ \time chalice deploy
Chaliceの実行結果
回数 chalice deploy実行時間(秒)
1回目 5.31
2回目 4.55
3回目 4.18

実行結果比較

SAMとChaliceの実行時間比較
回数/集計 SAMの実行時間[build+deploy](秒) chaliceの実行時間(秒)
1回目 21.79 5.31
2回目 23.94 4.55
3回目 22.99 4.18
平均 22.90 4.68

上記の結果の通り、簡単な変更でのデプロイ時間の比較ではChaliceの方が早いということがわかりました。

感想

Chaliceを初めて体験した時の通り結構デプロイスピードは早かったです。ChaliceはSAMやCDKのようにCloudFormationを通しての構築でなく直接リソースを生成しているので早いらしいです。(ハンズオンの時に聞きました)SAMやCDKはS3やDynamoDBの生成もできるので、Chaliceの使用用途は少ないかもしれないですが、1秒でも時間が惜しいハッカソンやスタートアップでWebAPIをガンガン作って壊してを繰り返したい時に使えそうです。気になった方は是非使ってみて下さい。