ちょっと話題の記事

Chalice の 1.0.0 GA がリリースされました

2017.08.01

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

こんにちは、藤本です。

現地時間 7/31 に Chalice の 1.0.0 GA がリリースされました。

プレビュー版が登場して、1年ちょっとで遂に GA リリースとなりました。(既に GA リリース済みかと思ってた。

【新機能】Python Serverless Microframework for AWS(プレビュー版)が登場!

Chalice

Chalice は API Gateway + AWS Lambda for Python の API 環境を実行するサーバレスフレームワークです。サーバレスフレームは SAM(Serverless Application Model) や Serverless Framework など既に多く存在しますが、Chalice はシンプルで Python ユーザーが簡単にサーバレス環境を管理・構築できることが特徴です。というのも、Chalice は Python の Web アプリケーションフレームワークの Flask ライクな実装となっていて、Flask を利用したことある方はパスルーティングの設定や、リクエスト、レスポンスの取り扱いはほぼそのままの知識でできます。Flask を利用したことがない方でもドキュメントを眺めるだけで簡単に習得することができます。

連携可能な AWS サービス

Chalice のプレビュー版リリース当初は下記 4サービスを連携して扱うことができました。

  • AWS Lambda
  • Amazon API Gateway
  • AWS Identity and Access Management (IAM)
  • Amazon CloudWatch

GA リリースまでに多くのサービスを連携して扱えるようになっていました。

  • AWS Lambda
  • Amazon API Gateway
  • AWS Identity and Access Management (IAM)
  • Amazon Cognito
  • Amazon CloudWatch
  • Amazon CloudWatch Events
  • AWS CloudFormation
  • AWS CodeBuild
  • AWS CodeCommit
  • AWS CodePipeline

パスルーティング

API Gateway はパスに対してリクエストの変換や、バックエンド処理を選択することができます。ただ、パス数が膨大にあるとそれを管理することは大変です。Chalice ではソースコード(Lambda for Python)側でパスに対して処理を実行する関数を紐付けることができます。

@app.route("/")
def hello_world():
    return {"hello": "world"}

@app.route("/test")
def test():
    return {"message": "test"}

デプロイ

Lambda のソースコードをマネジメントコンソールや、API/CLI などでアップロードするのは手間です。多くの方は Lambda のソースコードをデプロイする OSS などを使われているかと思います。Chalice はデプロイ機能を内包しています。コマンドベースでデプロイすることができます。単純なソースコードのアップロードだけでなく、依存ライブラリがあればrequirement.txtからインストールして Zip化したり、API Gateway や、IAM など関連するサービス設定を同時に行ってくれます。

また API Gateway と関連しない単純な Lambda Function のデプロイを実行することも可能です。

CI/CD

デプロイコマンドにより簡単に API 環境を構築・設定可能になりましたが、チーム開発となると、ソースコード管理や、自動テストや判定などと組み合わせてデプロイしたいかと思います。Chalice では CI/CD の仕組みを提供しています。と言っても、CodeCommit、CodeBuild、CodePipline を構成する CloudFormation テンプレート(JSON)を自動生成する機能を持っています。生成された CloudFormation テンプレートから CodeCommit、CodeBuild、CodePipeline、および関連する IAM Role が設定され、それらを利用する形となります。

$ chalice generate-pipeline <JSONファイル名>
$ cat <JSONファイル名>
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Outputs": {
    "S3PipelineBucket": {
      "Value": {
        "Ref": "ArtifactBucketStore"
      }
    },
:
<snip>

スケジュールイベント

Chalice は API 用途の管理だけではありません。関連サービスに CloudWatch Events と記載されていますが、CloudWatch Events(スケジュール実行)→ Lambda の構成も Chalice によって、管理、デプロイすることができます。

@app.schedule(Rate(12, unit=Rate.HOURS))
def handler(event):
    backup_logs()

IAM ポリシージェネレータ

サービス間連携で関連する IAM Role をデプロイ時に自動で生成/編集します。

認証

API システムにおいて、認証が必要になるケースは多く存在します。独自で認証機能を実装すると面倒ですが、Chalice は簡単に認証を実装する機能を持っています。更に認証のユーザー管理も IAM、Cognito ユーザープール、Lambda による独自実装と AWS の機能を活用した多くの認証方法があります。ソースコードで数行書くだけで簡単に実装できます。

IAM の利用
from chalice import IAMAuthorizer

authorizer = IAMAuthorizer()

@app.route('/iam-auth', methods=['GET'], authorizer=authorizer)
def authenticated():
    return {"success": True}
Cognito ユーザープールの利用
from chalice import CognitoUserPoolAuthorizer

authorizer = CognitoUserPoolAuthorizer(
    'MyPool', provider_arns=['arn:aws:cognito:0123456789:userpool/name'])

@app.route('/user-pools', methods=['GET'], authorizer=authorizer)
def authenticated():
    return {"success": True}
Lambda による独自実装
from chalice import CustomAuthorizer

authorizer = CustomAuthorizer(
    'MyCustomAuth', header='Authorization',
    authorizer_uri=('arn:aws:apigateway:region:lambda:path/2015-03-01'
                    '/functions/arn:aws:lambda:ap-northeast-1:0123456789:'
                    'function:FunctionName/invocations'))

@app.route('/custom-auth', methods=['GET'], authorizer=authorizer)
def authenticated():
    return {"success": True}

試してみた

それでは簡単にインストールから、API を返すところまで試してみます。

インストール

既に PyPI に 1.0.0 がリリースされていますので、pipコマンドで簡単にインストールできます。

pip install chalice
Collecting chalice
Requirement already satisfied: pip<10,>=9 in /Users/fujimoto.shinji/.pyenv/versions/3.6.0/envs/tmp/lib/python3.6/site-packages (from chalice)
Collecting typing==3.5.3.0 (from chalice)
  Downloading typing-3.5.3.0.tar.gz (60kB)
    100% |████████████████████████████████| 61kB 2.6MB/s
Collecting six<2.0.0,>=1.10.0 (from chalice)
  Using cached six-1.10.0-py2.py3-none-any.whl
Collecting botocore<2.0.0,>=1.5.40 (from chalice)
  Using cached botocore-1.5.91-py2.py3-none-any.whl
Collecting click==6.6 (from chalice)
  Downloading click-6.6-py2.py3-none-any.whl (71kB)
    100% |████████████████████████████████| 71kB 4.0MB/s
Collecting jmespath<1.0.0,>=0.7.1 (from botocore<2.0.0,>=1.5.40->chalice)
  Downloading jmespath-0.9.3-py2.py3-none-any.whl
Collecting python-dateutil<3.0.0,>=2.1 (from botocore<2.0.0,>=1.5.40->chalice)
  Using cached python_dateutil-2.6.1-py2.py3-none-any.whl
Collecting docutils>=0.10 (from botocore<2.0.0,>=1.5.40->chalice)
  Downloading docutils-0.13.1-py3-none-any.whl (536kB)
    100% |████████████████████████████████| 542kB 2.1MB/s
Installing collected packages: typing, six, jmespath, python-dateutil, docutils, botocore, click, chalice
  Running setup.py install for typing ... done
Successfully installed botocore-1.5.91 chalice-1.0.0 click-6.6 docutils-0.13.1 jmespath-0.9.3 python-dateutil-2.6.1 six-1.10.0 typing-3.5.3.0

Chalice プロジェクトの作成

Chalice 用のプロジェクトを作成します。

$ chalice new-project chalice-ga
$ cd chalice-ga

ソースコード作成

Hello World 的なソースコードとなりますが、

$ echo "from chalice import Chalice

app = Chalice(app_name='helloworld')


@app.route('/')
def index():
    return {'hello': 'world'}" >> app.py

デプロイ

$ chalice deploy
Initial creation of lambda function.
Creating role
Creating deployment package.
Initiating first time deployment...
Deploying to: api
https://06pn0o9fme.execute-api.ap-northeast-1.amazonaws.com/api/

動作確認

デプロイコマンドの実行結果にあるエンドポイントへリクエストを送信します。

$ curl https://06pn0o9fme.execute-api.ap-northeast-1.amazonaws.com/api/
{"hello": "world"}

/のパスで定義したindex関数が実行され、返り値がレスポンスとして返ってきました。非常に簡単ですね!

まとめ

いかがでしたでしょうか?
シンプルとは言え、気づけばたくさん機能が実装されていたので、もう少しちゃんと各機能を試してみて、改めてブログエントリしたいと思います。