Cloud Build と Cloud Run で Slack 通知を構成する
By dobassy
Hugo のサイトをビルドしてサーバーへデプロイするまでの一連のフローを Cloudbuild にて実現していますが、デプロイ結果の通知をやっていなかったので設定することにしました。もちろん手段は多数考えられるわけですが、GCP環境での利用だと何がよいのか調べたので選定経緯を含めて記したいと思います。
最初に結論
Cloud Build Notifier を Cloud Run 環境上で動かす方式を選定しました。Cloud Build Notifier は、Cloud Run 環境上でコンテナとして実行される Docker イメージです。
Picture Source: priyankavergadia/GCPSketchnote
調べる前は Clouf Functions にエンドポイントを作って通知することになるかなと想像していましたが、Cloud Run & Docker イメージを用いた構成のため、よりパッケージ化された構成で実現できました。手順が少ないかというと Secret Manager を使ったりPub/Subを使ったり、その他各種機能のAPIを有効化したりで工数面の比較のみだとどっちもどっちな印象はありますが、クラウドネイティブ感が出ているので試すことができてよかったなという印象です。
Clouf Functions でアプリを動かすか、Cloud Run 上でアプリを動かすかの違いであり、本質的には同じものと考えられます。
Slack 通知を構成する | Cloud Build のドキュメント | Google Cloud
このチュートリアルに従うことで、以下の GCP サービスを体験することができます。
- Cloud Build #主役
- Cloud Pub/Sub
- Cloud Run
- Cloud Build Notifier #これそのものはDockerイメージにすぎない
- Secret Manager
- HashiCorp の Vaultみたいにシークレット情報の一元管理とキーのライフサイクルをマネジメントしてくれるサービス。
- 興味はあったものの使う機会を作れていなかったので好都合でした。
- Cloud Storage
- Cloud Build Notifier の設定ファイルを1つ配置するために利用
以降はそれぞれ噛み砕きつつ記載します。やっていることは結局公式ガイドの内容をなぞっているだけですが、ところどころで理解の補足を書いています。
Slack 通知を実現するアーキテクチャ概要
概要理解を目的としていますので、言葉の節々は厳密には不正確です。大枠の把握として捉えてください。 ここを抑えておくと、チュートリアルの理解の助けになると思います。
-
Cloud Build が Cloud Pub/Sub に対してイベントを通知
- イベントは、「ビルド成功したよ!」とか「失敗したよ!」といった情報
-
Cloud Pub/Sub からのイベント連絡を待ち受けている Cloud Build Slack Notifier (サブスクライバー)が検知
-
Cloud Build Slack Notifier がSlackに対し通知
- 実装そのものは Go で書かれているシンプルなバイナリのようである
- cloud-build-notifiers/slack at master · GoogleCloudPlatform/cloud-build-notifiers · GitHub
実行環境として Cloud Run を用いているものの、アーキテクチャ上は存在感が薄いので、さほど意識しなくても自然と使っている感じです。Cloud Run そのものの料金は、少々使う程度ならば無料内に収まると思われます。
料金 | Cloud Run | Google Cloud(2021/11/14時点)
- 毎月最初の 180,000 vCPU 秒は無料
- 毎月最初の 360,000 GiB 秒は無料
- 毎月 200 万リクエストは無料
- 北米内の下り(外向き)は毎月 1 GiB まで無料
CPU、メモリ、リクエスト、そしてトラフィックという4つの指標で課金計算されるようですね。
前提条件
-
gcloud
コマンドが利用できること -
Cloud Build そのものの設定(
cloudbuild.yml
などを用いたビルド動作の設定)が済んでいること- この記事では、Cloud Build 実行後の結果を通知するための情報整理なのでフェーズが少々異なります
-
Slack の Inccoming Webhook を予め用意しておくこと
- むかーしから Inccoming Webhook を使っていて、かつたまにしか使わない場合、ふと気づくとSlackno画面構成が変わっていてこまることが度々あります。
- https://api.slack.com/apps/ にアクセスして、自身のSlackアプリを選択(なければ作成)する
- 「Incoming Webhooks」を選択
- 「Webhook URL」の欄にURLがある
- むかーしから Inccoming Webhook を使っていて、かつたまにしか使わない場合、ふと気づくとSlackno画面構成が変わっていてこまることが度々あります。
チュートリアルの補足
すべて公式チュートリアル通りなので全てをなぞることはせず、軽く補足をするに留めます。
チュートリアルには度々以下のような表現が出てきますが、赤い鉛筆の部分は編集可能で、いくつかで使いまわしをする文字列なので、入力しておくとその後のコピペが楽で便利だと思います。
(↑の鉛筆マーク)
以下の変数は頻出ですので準備しておきましょう。
-
project-id
gcloud config list
で現在の設定を確認可能。project
キー部分にある値。
-
project-number
- Cloud プロジェクト番号。手軽に確認するためのワンライナーは以下の通り。
gcloud projects describe $GOOGLE_CLOUD_PROJECT --format json | jq ".projectNumber | tonumber"
- ここで
GOOGLE_CLOUD_PROJECT
は、最初似確認したproject-id
を意図しています。
Cloud Run の実行準備
Cloud Run の実行が初めてと想定される場合は、以下のコマンドを叩いて確認しておくとよいでしょう。 gcloud run services list
は現在の設定状況(デプロイ状態)を確認できますが、初めての実行の場合は以下の通りAPIを有効化するか確認されます。(確認していませんが、初操作がいきなりデプロイでも同様の確認が出るのだろうとは思います)
$ gcloud run services list
API [run.googleapis.com] not enabled on project [123projectnumber890]. Would you like to enable and retry (this will take a few minutes)? (y/N)? y
Enabling service [run.googleapis.com] on project [123projectnumber890]...
Operation "operations/acf.p2-123projectnumber890-88887777-0000-1111-2222-33334444aaaa" finished successfully.
Listed 0 items.
なおこのチュートリアルを通じて一通りのセットアップが終わると、実行結果は以下のように表示されます。
SERVICE REGION URL LAST DEPLOYED BY LAST DEPLOYED AT
✔ yourname-slack-notifier us-westX https://yourname-slack-notifier-XXXXXXXXXX-XX.a.run.app example@gmail.com 2021-11-13T08:42:27.796066Z
IAM関連の設定
いくつかIAMの権限設定がありますが、それぞれ以下の目的に対して設定するものです。
- “Compute Engine のデフォルトのサービス アカウント” が、 Secret Manager を参照して情報を取得できるように権限付与する
- Cloud Run サービスアカウントが Cloud Storage バケットを参照するために “Compute Engine のデフォルトのサービス アカウント” にストレージオブジェクト閲覧権限を付与する
- プロジェクトに認証トークンを作成する Pub/Sub 権限を付与する
- cloud-run-pubsub-invoker サービスアカウントに Cloud Run Invoker 権限を付与する
Notifier 構成ファイルを作成
apiVersion: cloud-build-notifiers/v1
kind: SlackNotifier
metadata:
name: example-slack-notifier
spec:
notification:
filter: build.status == Build.Status.SUCCESS
delivery:
webhookUrl:
secretRef: webhook-url
secrets:
- name: webhook-url
value: projects/project-id/secrets/secret-name/versions/latest
Notifier の設定ですが、Kubernetesそのものって感じのコンフィグです。spec.notification.filter
に記載されている条件式で通知対象の挙動を変更できるようです。詳しくはマニュアルに複数のパターンが記載されています。
Notifier を Cloud Run にデプロイ
gcloud run deploy service-name \
--image=us-east1-docker.pkg.dev/gcb-release/cloud-build-notifiers/slack:latest \
--no-allow-unauthenticated \
--update-env-vars=CONFIG_PATH=config-path,PROJECT_ID=project-id
image
はGoogleが提供している Docker Image のレジトリーです。
config-path
は、格納した設定ファイルの場所を示すCloud Storage のバケットを含むフルパスを記載します。gs://...
Cloud Build から通知する先は cloud-builds トピック
Cloud Build では、ビルドの作成時、ビルドの動作状態への移行時、ビルドの完了時など、ビルドの状態が変化したときに Google Pub/Sub トピックにメッセージを公開します。Cloud Build がビルド更新メッセージを公開する Pub/Sub トピックは cloud-builds です。
とのことで、トピック名は固定のようです。
なお トピック と サブスクリプション という単語が出てきますが、トピックが入り口、サブスクリプションが出口(サブスクライバー≒アプリケーションがイベント待受をする場所)と捉えれば概ね困らないかと思います。サブスクリプションも自由に名前をつけられるのがかえって面倒ですが、cloud-builds-subscriber
みたいな名前にするなど、適当で構いません。
ビルド通知へのサブスクリプション | Cloud Build のドキュメント | Google Cloud
Secret Manager
今回のチュートリアルでは画面操作でしたのでコマンドはありませんでしたが、以下の通り別のガイドも存在しています。
Secret Manager では、シークレットをバイナリ blob またはテキスト文字列として保存、管理、アクセスできます。適切な権限を使用して、シークレットのコンテンツを表示できます。
Secret Manager は、実行時にアプリケーションが必要とする構成情報(データベース パスワード、API キー、TLS 証明書など)を保存するのに便利です。
クイックスタート | Secret Manager のドキュメント | Google Cloud
Kubernetes なんかを使っていると ConfigMap
や Secret
の構成ファイル管理が煩雑になってくるほか、そもそもシークレット系の情報をテキストファイルで管理するのはもろもろ気分がよくありませんので、この手のシークレットマネージャーに一元化していくのが望ましいと思います。(まだ実用的なレベルで活用したことがないので表面的な意見に留めます)
まとめ
Cloud Functions でサクッと Slack 通知機能を作ってしまうのが手っ取り早かったとは思いますが、同じ技術の繰り返しも面白くないので新しい構成にトライしました。GCPのドキュメントがしっかりしているので特に困る部分はないのですが、手順をなぞる上で意味の確認などで時間をとった部分もありますので、復習も兼ねて記録しました。
少しでも理解の補助になればと思います。