PR上でCDKのレビューやデプロイを行うツールcdkbotを作った

awsproductcirclecigolang

sambaiz/cdkbot

PRのコメントで/diff/deployと打つとcdk diffcdk deployが走る。 diffを見てレビューし、良ければ/deployでデプロイし完了するとmergeされる。

diff & deploy

以前CircleCIでmerge時にdeployされる仕組みを作った。

CDK/CircleCI/GitHubでAWSリソース管理リポジトリを作る - sambaiz-net

ただ、この仕組みだと CFnの実行時エラーのためにデプロイできない状態のものがmasterブランチにmergeされてしまい、その修正のために何回も試行錯誤のPRを出すことになったり、 Stack間の依存がある場合リソースを削除するとcdk deployによって依存解決された順序だと失敗してしまうという問題があった。 cdkbotでは必要ならデプロイするStackを選べて、完了してからmergeすることでこれらの問題を解決した。 また、AWS外のCIにとても強い権限を与えていたがそれも必要なくなった。

単純にブランチの状態でデプロイしてしまうと古い状態に巻き戻ってしまう可能性があるので、内部でbaseブランチをmergeしていたり、 ラベルによってそのPRがデプロイ可能かどうかを制御していたりする。 最低限デプロイできるようになってから、この辺りの仕組みを整えるまでに存外に時間がかかった。

Serverless Application Repositoryに公開してあるので簡単にインストールできる。

AWS SAMでLambdaの関数をデプロイしServerless Application Repositoryに公開する - sambaiz-net

追記 (2019-10-26): ap-northeast-1に対応していないのと、ECSのリソースを作成できないため、Serverless Application Repositoryに公開するのはやめた。makeでインストールできる。 Lambda環境でできない処理をECSで実行する - sambaiz-net

外部コマンド

gitやnpmといった外部コマンドを実行する必要があるが、標準では入っていないのでLambda Layerで入れている。

Lambda上でnpm installできるLayerを作った - sambaiz-net

Go moduleのキャッシュ

Dockerコンテナ内でテストを実行しているが、毎回go moduleの解決が走ることで時間はかかるし、テザリングの容量に大打撃を受けたので、 ローカルのキャッシュをコピーするようにした。

test:
	docker build -t cdkbot-npmbin ./npm-lambda-layer
	docker build -t cdkbot-test -f ./test/Dockerfile .
	docker rm -f cdkbot-test || true
	docker run -itd --name cdkbot-test cdkbot-test /bin/sh
	docker cp . cdkbot-test:/root/cdkbot
	go mod download
	docker cp `go env GOPATH`/pkg/mod/cache cdkbot-test:/go/pkg/mod/cache
	docker exec cdkbot-test make _test
	docker rm -f cdkbot-test

_test:
	go test ./...

CircleCIではキャッシュをキャッシュしている。

- restore_cache:
  keys:
    - gomod-cache-v1-{{ checksum "go.sum" }}
    - gomod-cache-v1-
...
- save_cache:
  key: gomod-cache-v1-{{ checksum "go.sum" }}
  paths:
    - /go/pkg/mod/cache