LoginSignup
2
1

More than 1 year has passed since last update.

ChaliceのCDパイプラインをシンプルに構築する

Last updated at Posted at 2021-09-14

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を作成します。

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に入れてしまいましょう。

buildspec.yml
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入ってないよ」というエラーが出ます。
とりあえずインポートエラーを補足するワークアラウンドでしのぎました。

app.py
import warnings

try:
    import pyodbc
except ImportError:
    warnings.warn("pyodbcをインポートできません。CD環境の場合はこの警告を無視できます。")

まとめ

ローカルでもCDでも同じ方法でデプロイすることができました。
CloudFormation版では何をしたかったのかを読み解けておらず、まずい点があったら教えていただきたいです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1