この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
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のパッケージ化を検討してみましょう。