Serverless Frameworkプロジェクトと開発者アセットのCDを回す
前回の続きです。
mao-instantlife.hatenablog.com
mao-instantlife.hatenablog.com
GithubにコードがプッシュされたらServerlessプロジェクトをデプロイし、デプロイ後のAPIドキュメントやクライアントライブラリの生成を継続的にする環境を作ってみましょう。
閑話:外部パッケージ管理の修正
最初からかよ、とか言わない。前回、とあるLambdaファンクションを作る際に外部ライブラリを必要としました。とりあえずは .gitignore
に追加してローカルで pip install
することでお茶を濁していましたが、やはりかっこ悪いですし、CD環境作るには微妙なところでもあるのでプラグインを導入してなんとかします。
やはり誰かが考えてるものですよね、遠慮なく乗っからせていただきます。ちなみに、クラメソさんの以下の記事を参考にして使い始めたけど、少しバージョンアップして使い方が変わったっぽいです。最新はドキュメントをみましょう。
ローカルでは普通にグローバルに pip install
してパスを通して使うという場合はプラグインを入れて requirements.txt
を使う感じです。特にプロダクトコードに記載を加える必要はありません。
グローバルに pip install
せずに requirements.txt
の設定を元にローカルでもキックするよ、という場合は外部ライブラリをzipにまとめて使う設定にしましょう。 serverless.yml
に以下の設定を追加します。
custom: pythonRequirements: zip: true
その上で、対象の外部ライブラリを使うコードの前に
import unzip_requirements
を追加します。
ダウンロードしたライブラリや自動生成されるコードのなどがあるので、以下は.gitignoreに追加しておくのが良いと思います。
.requirements
.requirements.zip
unzip_requirements.py
閑話休題:CD環境の整理
前回の構想、こんな感じでした。
Github(merge)-> CodeBuild -> CodeDeploy -(API Gateway)-> クライアントライブラリの生成とSwagger UIの更新
今回、CodePipelineで全体を管理できないか調べてみました。
CodePipeline is 何?
リリースのための手順、フローのモデル化、自動化のためのAWSのサービスです。で、調べ始めたんですが、割とつらみがあるっぽいです。
CircleCIでいいんじゃない?
ですよねー。
というわけでCircleCIをおさらいしてみました。前にちょっと使ってた時は1系だったので少し進化してましたね。
- ビルドやテスト実行はDockerが基本になってる
- 複数のイメージの連携もCirclCIがよしなにしてくれる
- ジョブ毎に個別のイメージが使える
- AWSへのデプロイ設定も楽
カスタムコンテナを使う
で、今回のプロジェクトはServerless Framework + Python3なわけですので、ビルド環境のイメージは専用に作ってあげる必要があります。基本的なビルド環境についてはCircleCIが使う各種ツールがインストールされた状態でのオフィシャルイメージがあるので、nodeから派生させることにしましょう。
イメージは .config/images
にDockerfileをおくか、リポジトリにプッシュしておいてもいいです。構成が決まればイメージは共有できて、必要なミドルウェアは別のイメージで配備するというてもあるので、Dockerhubとかにプッシュしておくのが楽だと思います。
というわけで出来上がったのがこちらのイメージ。Dockerhubにも公開していますので、必要な方はご自由にどうぞ。
Serverless Framework + Python3で使うPythonのバージョンが3.6で、apt-getでインストールできるPythonが3.4だったし、いくつかググって出てきたバージョン3.6があると思しきリポジトリは追加しても404だったりで、結局イメージないでコンパイル・インストールしています。このあたりはもっとスマートに行きたいところだったんですが。。。
今回はデプロイまでなのでJREをインストールしていませんが、テストを流すとなるとDynamoDB Localを使うことになるのでJREのインストールが必要になります。これもこれで面倒臭いというか、LocalStackとかの利用で別のイメージ前提にした方がいいのではないかと考え中です。
閑話:serverless-step-functionsプラグインの制約にハマる
で、意気揚々とイメージ作ってデプロイしてみたら sls invoke stepf
が動かないわけですよ。実はローカルで実行してみても同様だったと。StateMachineが見つからないとか言われます、そんなバカな。で、色々とごにょごにょしていて、StateMachineの設定からname属性を外し、命名をキャメルケースにしたらできました。実際にデプロイされた時の名前はこんな感じです。
MyAssistantGenerateClientStepFunctionsStateMachine-************
末尾はなんかハッシュっぽい、念のためマスクしています。この末尾の部分はデプロイするステージを変更したら変わりました。この辺普通に文字列でつけたりできないか確認したいところ。まあ、Step Functionsへのキックイベントも serverless.yml
で書けるので実際問題はそこまできにする必要がないのかもしれませんが。
で、前回までの命名とname属性で登録された名前がこちら。
MyDashassistantDashgenerateDashclientDashdev-************
なんかname属性がある場合とか、変換とか文字数とかいくつか原因はありそうな気がします。とりあえず現状はそんなに細かい命名をしたいわけではないので、上の対応策でなんとかしました。
閑話休題:継続的デプロイの設定
というわけで今回の内容を反映した .circleci/config.yml
がこちらです。走り過ぎても面倒臭いので現状はmasterへのプッシュ、マージの時のみ発動、CodeGeneratorもまだ常時キックする感じでもないためStepFunctionsの設定をパスするように変更しています。
version: 2 jobs: build: docker: - image: shinsukeabe/circleci-serverless-python3:latest steps: - checkout - run: name: install project dependencies plugins command: sudo npm install serverless-dynamodb-local - run: name: deploy serverless functions command: sls deploy -v - run: name: distribute developers assets command: sls invoke stepf --name myAssistantGenerateClient general: branches: only: - master
まとめ
というわけで、CircleCIで自動デプロイまで仕掛けました。今回テストは仕掛けてませんが、ここまでできて入れば後は細かいつらみとの戦いになります。ここからしばらくはServerlessとLambdaの使い方を深めていく方向に試していこうかと思います。KMSとか使ってないですし、Lambdaに合ったデータの永続化のあり方とか。キリが良くなったら続けます。