😽

Pub/Subを使いCloudBuildの実行結果をSlackに通知する。

2022/07/13に公開約5,300字

はじめに

CloudBuild の実行完了結果をSlackへ通知した時の備忘録を書きます。
構成ファイルにSlack通知を行うステップを追加することも可能ですが、

  • 複数のcloudbuildトリガーが存在する場合、それぞれの構成ファイルに同じ処理を書くのは冗長になる
  • Buildと通知を分離しないと通知の変更がデプロイに影響を与えてしまう

ため構成ファイルを書き換えない方針で通知を実現できないか調査しました。

https://kumaaaaa.com/slack-notifications-for-cloud-build

こちらの記事を見つけたので、記事に従って構築しました。
カスタマイズした点に絞って、説明を記載していきます。

環境構築に必要な項目は以下となります。

  • Cloud Build, Compute Engine, Cloud Run, Pub/Sub, and Secret Manager API が有効化されたGCP環境
    有効化はこちら

  • Google Cloud CLI

  • Webhook設定の済んだ Slackワークスペース

概要

  1. トリガーに応じてCloudBuildでデプロイが実行される
  2. デプロイの実行が終了する
  3. Pub/Sub へビルドの実行終了がPushされる
  4. Pub/Sub のビルドの実行終了をサブスクライブしているCloudRunがイベントを受信する
  5. 受信したイベントに応じてSlackへ通知を行う

注意事項としてCloudBuildで使用される Pub/Subのトピック名は cloud-builds と固定されています。

各サービスが具体的にどのような役割を担っているかは下記の記事が分かりやすかったので、参照ください。

https://exlair.net/cloudbuild-and-cloudrun-with-slacknotifier

セットアップ

GCPの公式によってテンプレートが提供されているので、
こちらを使って構築していきます。
リポジトリはこちら

こちらの記事を参考にセットアップを完了させてください。

フィルターをカスタマイズ

apiVersion: cloud-build-notifiers/v1
kind: SlackNotifier
metadata:
  name: example-slack-notifier
spec:
  notification:
    filter: true
  secrets:
  - name: webhook-url
    value:

設定ファイルの filter プロパティでフィルター条件をカスタマイズすることができます。
カスタマイズの種類を何種類か記載します。
より詳細な情報は Slack 通知を構成する を参照してください。

  • トリガーID によるフィルタリング

以下のように指定することで、指定したトリガーのみで通知を実行することが可能です。
トリガの名称ではなく、IDであることに注意してください

filter: build.build_trigger_id == trigger-id

またトリガーのIDは

gcloud beta builds triggers list |grep -E '^(id|name|---)'

で取得することが可能です。

  • ステータスによるフィルタリング

Buildのステータスによってフィルタリングすることが可能です。
また in を使って複数の状態でフィルタリングすることも可能です。

filter: build.status == Build.Status.SUCCESS && build.build_trigger_id == trigger-id
filter: build.status in [Build.Status.FAILURE, Build.Status.TIMEOUT]
  • タグによるフィルタリング

build.tags を使用することでトリガーに紐づくタグで
フィルタリングすることが可能です。

filter: tag-name in build.tags
  • 変数によるフィルタリング

build.substitutionsを使うことで柔軟なフィルタを行うことが可能です。

filter: build.substitutions[substitution-variable] == substitution-value
build.substitutions["BRANCH_NAME"] == "main"

メッセージをカスタマイズ

デフォルトの通知メッセージでは味気ないことやどのトリガーが実行された結果なのか
URLをクリックして見に行かないといけないため、メッセージをカスタマイズしました。

リポジトリの中を見ると

https://github.com/GoogleCloudPlatform/cloud-build-notifiers/blob/master/slack/main.go#L101

writeMessage関数でメッセージを作る処理をしているので、アレンジしていきます。
複数トリガがある + 複数のブランチでデプロイしているので、
トリガ名とブランチ名を通知内容に含めます。

func (s *slackNotifier) writeMessage() (*slack.WebhookMessage, error) {
+ subs := build.Substitutions

+ triggerName := ""
+if val, ok := subs["TRIGGER_NAME"]; ok {
+    triggerName = val
+}
+
+var branch string
+if val, ok := subs["BRANCH_NAME"]; ok {
+    branch = val
+}
+
+txt := fmt.Sprintf(
+    "Cloud Build でデプロイが完了しました。\n trigger: %s \n branch: %s \n status: +%s",
+    triggerName,
+    branch,
+    build.Status,
+)

---
+ atch := slack.Attachment{
+     Text:  txt

ソースコードの修正が完了したら再度デプロイを行なっていきます。

デプロイ時に Buildと gcrへのpushを追加で実行します。

https://github.com/GoogleCloudPlatform/cloud-build-notifiers/blob/a7045a46ea763837f6af68838a16cb05a91fee24/setup.sh#L88:L97
- IMAGE_PATH="us-east1-docker.pkg.dev/gcb-release/cloud-build-notifiers/${NOTIFIER_TYPE}:latest"
+ IMAGE_PATH="asia.gcr.io/${PROJECT_ID}/notifier:latest"
}

https://github.com/GoogleCloudPlatform/cloud-build-notifiers/blob/a7045a46ea763837f6af68838a16cb05a91fee24/setup.sh#L159:L165
deploy_notifier() {
+ docker build . -t ${IMAGE_PATH} --platform linux/amd64 -f "./slack/Dockerfile"
+ docker push ${IMAGE_PATH}
  gcloud run deploy "${SERVICE_NAME}" \
    --image="${IMAGE_PATH}" \
    --no-allow-unauthenticated \
+    --max-instances=1 \
    --update-env-vars="CONFIG_PATH=${DESTINATION_CONFIG_PATH},PROJECT_ID=${PROJECT_ID}" ||
    fail "failed to deploy notifier service -- check service logs for configuration error"
}

再度デプロイコマンドを実行して、準備完了です!

bash ./setup.sh slack ./slack/slack.yaml

実際に通知すると画像のようになります!

補足

ソースコードを直接変更するのはあまり良い解決策ではないと思うので、filterと同じように
テンプレートを作って、埋め込みができるようにするというのが良い修正方法であるかなと思っています。
Issue にもあるので、トライしたい気持ちもあります。

むすびに

sweeepでは一緒に働くエンジニアを募集しています!
自動化大好き!インフラ効率化したい!技術大好き!
なエンジニアの方一緒に働きましょう!

https://corp.sweeep.ai/recruit

参考

執筆にあたり以下の記事を参考にさせてもらいました。大変助かりました。

https://cloud.google.com/build/docs/configuring-notifications/configure-slack#filtering_by_status

https://kumaaaaa.com/slack-notifications-for-cloud-build

https://exlair.net/cloudbuild-and-cloudrun-with-slacknotifier/
GitHubで編集を提案

Discussion

ログインするとコメントできます