What is chalice?
AWSが提供するPythonのサーバーレスフレームワークで、flaskみたいな書き心地でLambdaなどにデプロイできます。
今回はこのChaliceのCDを構築するお話。
TL;DR
Chaliceは自動でCDパイプラインを構築する機能がある。でもなんか難しくて結局自分で作った。
使用バージョン
- chalice==1.24.1
Deploy Command
公式ドキュメントのQuickstartではローカル環境からCLIでデプロイする方法が紹介されています。
$ chalice deploy --stage dev
1コマンドで簡単!
しかしこれだとチームで開発している場合は問題になります。
Chaliceは作成したAWSリソースを把握するため、.chalice/deployed/
配下に下記のようなJSONを作成します。
{
"resources": [
{
"name": "foo_role",
"resource_type": "iam_role",
"role_arn": "arn:aws:iam::...",
"role_name": "foo"
},
{
"name": "foo_lambda",
"resource_type": "lambda_function",
"lambda_arn": "arn:aws:lambda:ap-northeast-1:..."
},
{
"name": "foo_event",
"resource_type": "s3_event",
"bucket": "foo-dev",
"lambda_arn": "arn:aws:lambda:ap-northeast-1:..."
}
],
"schema_version": "2.0",
"backend": "api"
}
ローカルでデプロイする際にこのJSONがチームで共有できていないとリソースの作成・更新・削除がうまくできないわけです。
このあたりはterraformのtfstateに似てる。
CI/CD pipeline generation
そのため、ChaliceはCodePipelineによるCDパイプラインを自動的に構築する機能を持っています。
→ https://aws.github.io/chalice/topics/cd.html
$ chalice generate-pipeline --pipeline-version v2 pipeline.json
このコマンドを打つとCloudFormation用の設定ファイルが吐き出されます。
吐き出された設定ファイルを元にCloudFormationを使うことでCDパイプラインが出来上がるという二段構えです。ややこしい
CloudFormation??
CDパイプラインのための設定が自動で出来上がっていいじゃないか。最初はそう思いました。
デフォルトの設定で十分な方はこれでもいいかもしれません。しかしドキュメントにはこんなワードがありました。
Chalice can generate a CloudFormation template that will create a starter CD pipeline.
そうstarterなのです。
プッシュしたら自動的にデプロイしてほしい。デプロイしたら通知がほしい。そういうオマケは自前で作る必要があります。
「でも実は私、CloudFormation使ったことない。」
さあ困った。CloudFormationがわかる方は生成された設定をいじればいいと思います。
以降は私のようなCloudFormationワカラナイ人向けです。
Be Simple
そもそもローカルでデプロイするときはchalice deploy
の1コマンドで済んだのに、CDになると複雑すぎない?という疑問もあり、勝手知ったるCodeBuildでchalice deploy
させる方針を取ります。
問題になるのは状態を持っているdeployed.json
ですが、tfstateのようにS3に入れてしまいましょう。
version: 0.2
phases:
install:
runtime-versions:
python: 3.8
commands:
- python -V
pre_build:
commands:
- echo Install dependencies...
- pip install -r requirements.txt
- aws s3 cp s3://chalice-deployed/${STAGE}.json .chalice/deployed/${STAGE}.json || true
build:
commands:
- echo Deploy ${STAGE}...
- chalice deploy --stage ${STAGE}
post_build:
commands:
- aws s3 cp .chalice/deployed/${STAGE}.json s3://chalice-deployed/${STAGE}.json
- echo Build completed at `date '+%Y-%m-%d %H:%M:%S'`
うん。シンプル。
初回は${STAGE}.json
がなくダウンロードに失敗するので|| true
でごまかしてます。
念の為、CodeBuildの同時ビルド制限を1にしておきます。
完成!
ハマったところ
今回Chaliceで作成したLambda関数は一部Layerでpyodbcを入れていました。
requirements.txt
に入れてもChaliceがパッケージングできないライブラリだからです。
こうしたrequirements.txt
に書いていないライブラリがあるとCodeBuildでchalice deploy
したときに「pyodbc入ってないよ」というエラーが出ます。
とりあえずインポートエラーを補足するワークアラウンドでしのぎました。
import warnings
try:
import pyodbc
except ImportError:
warnings.warn("pyodbcをインポートできません。CD環境の場合はこの警告を無視できます。")
まとめ
ローカルでもCDでも同じ方法でデプロイすることができました。
CloudFormation版では何をしたかったのかを読み解けておらず、まずい点があったら教えていただきたいです。