[CircleCI]requiresとfiltersの指定を適切に組み合わせてapprove通知を適正にした記録
はじめに
CICD実行時に更新を含まないbuildやdeployを避ける目的で、buildとdeployの発生直前にManual Approveを挟んでみました。結果として無意味なbuildやdeployにリソースを浪費することはなくなったのですが、今度は伴って発生するSlackへの通知が過多になってしまいました。
勿論必要なApproval通知もあるのですが、明らかに自動処理を寸止めするためだけのApproval通知の方が多く、操作を誤ると事故の原因となります。
- 必要な時にはApprove通知を飛ばす
- 寸止めしたい時にはApprove通知を飛ばす以前にWorkflowをそのものを終わらせる
という形を目指して、試行錯誤ながらも試してみた内容が期待通りの結果となったため、備忘録としてまとめてみました。
Approve通知に関する要件
ベースは以下のエントリーです。当時は開発環境のみの設定でしたが、現在は本番環境の設定も含んでいます。
まず、「通知が必要な時」と「通知が必要ではない時」の2つに分けました。その上で、それぞれのjobを動かすための前提をfilterとして当てはめます。
github-flowを利用しており、tag作成はmasterブランチから行われます。
CICDの処理 | フックとなる更新 | 通知 | 環境 |
---|---|---|---|
build | masterブランチ更新 | 要 | 開発 |
deploy | masterブランチ更新 | 要 | 開発 |
deploy | tag作成 | 要 | 本番 |
test | masterブランチ更新 | 不要 | 開発 |
test | 作業ブランチ更新 | 不要 | 開発 |
ワークフローに関する要件
Approveの通知の構成から、それぞれ以下の流れとなります。
- 作業ブランチ更新
- test
- masterブランチ更新
- test + build + development deploy
- tag作成
- production deploy
WorkFlowのrequires設定
すでに組まれているbatch test、build、deployのjobに対して、requiresとfiltersを更新します。
test
作業ブランチ更新の際のフローです。branchはどんな命名パターンでも受け付けます。承認通知は送られません。
jobs: - test: python-version: "3.6" filters: tags: ignore: /.*/ branches: only: /.*/ context: xxxx
test + build + development deploy
masterブランチ更新の際には、testフローに加えて以下のフローが走ります。buildと開発環境deploy時に承認通知が送られます。
- slack/approval-notification: message: ${CIRCLE_BRANCH}をbuildするためにはApproveが必要です。 requires: - test context: xxxx filters: tags: ignore: /.*/ branches: only: master - approve_build: type: approval requires: - test context: xxxx filters: tags: ignore: /.*/ branches: only: master - aws-ecr/build-and-push-image: requires: - approve_build context: xxxx dockerfile: 'docker/Dockerfile' repo: 'XXXX' filters: tags: ignore: /.*/ branches: only: master - slack/approval-notification: message: ${CIRCLE_BRANCH}を開発環境へdeployするためにはApproveが必要です。 requires: - aws-ecr/build-and-push-image filters: tags: ignore: /.*/ branches: only: master context: xxxx - approve_deploy_dev: type: approval requires: - aws-ecr/build-and-push-image filters: tags: ignore: /.*/ branches: only: master context: xxxx - deploy_dev: requires: - approve_deploy_dev python-version: "3.6" context: xxxx filters: tags: ignore: /.*/ branches: only: master
production deploy
tag作成の際には以下のフローが走ります。tagはどんな命名パターンでも受け付けます。本番環境deployの承認通知が送られます。
- slack/approval-notification: message: ${CIRCLE_TAG}を本番環境へdeployするためにはApproveが必要です。 filters: tags: only: /.*/ branches: ignore: /.*/ context: xxxx - approve_deploy_prod: type: approval filters: tags: only: /.*/ branches: ignore: /.*/ context: xxxx - deploy_prod: requires: - approve_deploy_prod python-version: "3.6" filters: tags: only: /.*/ branches: ignore: /.*/ context: xxxx
通して一つのconfigにする
上記の各jobsを一つのワークフローにまとめます。最初は「本当にこれで問題ないのだろうか」と思いましたが、実際に走らせてみるとfilterに応じてworkflowが変化していました。
workflows: version: 2 cicd_pipeline: jobs: - test: python-version: "3.6" filters: tags: ignore: /.*/ branches: only: /.*/ context: xxxx - slack/approval-notification: message: ${CIRCLE_BRANCH}をbuildするためにはApproveが必要です。 requires: - test context: xxxx filters: tags: ignore: /.*/ branches: only: master - approve_build: type: approval requires: - test context: xxxx filters: tags: ignore: /.*/ branches: only: master - aws-ecr/build-and-push-image: requires: - approve_build context: xxxx dockerfile: 'docker/Dockerfile' repo: 'XXXX' filters: tags: ignore: /.*/ branches: only: master - slack/approval-notification: message: ${CIRCLE_BRANCH}を開発環境へdeployするためにはApproveが必要です。 requires: - aws-ecr/build-and-push-image filters: tags: ignore: /.*/ branches: only: master context: xxxx - approve_deploy_dev: type: approval requires: - aws-ecr/build-and-push-image filters: tags: ignore: /.*/ branches: only: master context: xxxx - deploy_dev: requires: - approve_deploy_dev python-version: "3.6" context: xxxx filters: tags: ignore: /.*/ branches: only: master - slack/approval-notification: message: ${CIRCLE_TAG}を本番環境へdeployするためにはApproveが必要です。 filters: tags: only: /.*/ branches: ignore: /.*/ context: xxxx - approve_deploy_prod: type: approval filters: tags: only: /.*/ branches: ignore: /.*/ context: xxxx - deploy_prod: requires: - approve_deploy_prod python-version: "3.6" filters: tags: only: /.*/ branches: ignore: /.*/ context: xxxx
あとがき
全く条件が異なるfilterを持つjobを混在させた場合に、正常に動作するのか不安でしたが、いずれの前提の場合も問題ありませんでした。
ただ、filterの条件が複雑になってくると、CICDの要件が増えた際にミスが発生しやすくなります。その場合はConfigのパッケージ化を検討してみましょう。