私は今まで、このブログの記事を投稿するたびに Cloud Build のコンソールを開き、デプロイの完了を目視で確認していました。

ほぼ 4 年(!)続けていて、さすがに面倒になったので、重い腰を上げて [2015-03-08-1] でも紹介した Pushover に通知できるようにしました。

その過程で、Docker image のビルドを Cloud Build から GitHub Actions に移行しました。そこから芋づる式に、Artifact Registry の掃除や Terraform 管理、IAM の整理まで進みました。

結果として、通知できるようになっただけでなく、シンプルになり、速くなり、Artifact Registry の容量も減りました。

なぜ今さらデプロイ通知なのか

[2022-10-01-1] に書いたとおり、このブログは 2022 年 9 月に Heroku から Cloud Run に移行しました。

Heroku で動かしていた頃は、デプロイ完了の Pushover 通知を簡単に設定できました。Cloud Run に移行してからは通知がなくなり、冒頭のとおりコンソールで確認するという状態で放置していました。

だいぶ前に一度、Cloud Build の公式ドキュメント にある cloud-build-notifiers を試しました。Pub/Sub と Cloud Run を使って HTTP 通知を送る仕組みですが、手順が多く、途中で挫折しました 😅

Google Cloud 側で実装する前提で考えていた

Cloud Build でビルドしてデプロイしている以上、通知も Google Cloud 側で実装する前提で考えていました。

実際には、デプロイのトリガーを GitHub Actions に移行すれば済む話でした。Pushover への通知なら、[2026-02-23-1] で作った自分用の reusable workflow がすでにあります。

まずは GitHub Actions から gcloud builds submit を同期実行し、完了したら Pushover に通知するようにしました。ビルドとデプロイは Cloud Build のままで、GitHub Actions はその完了を待つだけです。これで長年の悩みが解消し、通知が届くようになりました。

ついでに、Test の成功を待ってからデプロイできるようにもしました。それまでは GitHub Actions の Test と Cloud Build のトリガーが同時に動いていたので、Test が落ちてもデプロイされていました。

この時点の Deploy ワークフローはこんな感じです。

jobs:
  test:
    uses: ./.github/workflows/test.yml
  deploy:
    needs: test # Test の成功を待つ
    steps:
      - name: Deploy to Cloud Run via Cloud Build
        run: gcloud builds submit . --config=cloudbuild.yaml # Cloud Build の完了を待つ
  pushover_success:
    if: success()
    needs: [test, deploy]
    uses: masutaka/actions/.github/workflows/pushover.yml@main
    with:
      status: success
  pushover_failure:
    if: failure()
    needs: [test, deploy]
    uses: masutaka/actions/.github/workflows/pushover.yml@main

ここで、GitHub Actions は Cloud Build の完了を待っているだけだと気付きました。ビルドも GitHub Actions で実行すれば、間のレイヤーが 1 つ減ります。

なぜビルドまで GitHub Actions に移行したのか

最初は、レイヤーが 1 つ減るなら試してみようという程度でした。試しに移行してみたらデプロイが速くなったので、そのまま移行しました。どのくらい速くなったかは次のセクションで書きます。

AWS でも、CodeBuild を使わずに GitHub Actions でビルドしてデプロイする構成はよく見かけます。今回の構成も、それとほぼ同じです。

GitHub Actions で docker build して Artifact Registry に push し、gcloud run services update でデプロイするようにしました。Google Cloud への認証は Workload Identity Federation で、長期 credential である SA(Service Account)キーは使っていません。

移行後の Deploy ワークフローはこんな感じです。

jobs:
  deploy:
    steps:
      - name: Build
        run: docker build --build-arg HUGO_ENV_ARG=production -t "$IMAGE" .
      - name: Configure Google Cloud Credentials
        id: google-credentials
        uses: google-github-actions/auth@... # v3.0.0
        with:
          workload_identity_provider: ${{ vars.GOOGLE_WORKLOAD_IDENTITY_PROVIDER }}
          service_account: ${{ vars.GOOGLE_SERVICE_ACCOUNT_DEPLOY }}
      - name: Push
        run: |
          gcloud auth configure-docker asia-northeast1-docker.pkg.dev --quiet
          docker push "$IMAGE"
      - name: Deploy to Cloud Run
        run: |
          gcloud run services update masutaka-net \
            --region=asia-northeast1 \
            --image="$IMAGE" \
            --quiet

ビルドに失敗したときのログは、GitHub Actions にそのまま出力されます。Cloud Build のコンソールを見に行く必要はなくなりました。

どのくらい速くなったのか?

ビルドから Cloud Run への反映までの時間を比較します。

時期 方式 所要時間
〜9/21 Cloud Build トリガー 1 分 45 秒〜2 分 6 秒
9/21〜9/22 GitHub Actions から gcloud builds submit 2 分 20 秒〜2 分 58 秒
9/22〜 GitHub Actions でビルドしてデプロイ 1 分 1 秒〜1 分 24 秒

途中で一度遅くなったのは、GitHub Actions からソースを tar にまとめて Cloud Storage にアップロードする処理が増えたためです。ビルドまで GitHub Actions に移行すると、アップロードも Cloud Build の VM 起動もなくなり、2 分前後から 1 分強になりました。

芋づる式に片付いたこと

Cloud Run に移行してからほぼ 4 年、コンソールで作った設定をそのまま放置していました。それでも困らなかったのは、Cloud Run を含む Google Cloud が安定していたからです。インシデントがあった記憶はほぼありません。

ただ、放置できていたからこそ、Artifact Registry の肥大化や過剰な権限、コード化されていないリソースに気付きませんでした。今回、それらもまとめて片付けました。

Artifact Registry の容量

1,327 個の Docker image が一度も消されずに溜まり、45.5 GB になっていました。

cleanup policy を設定し、最新 10 件を残して 90 日より古いものを削除するようにしました。結果は 3 GB で、93% 減です。

ほぼすべてを Terraform 管理に

2022 年にコンソールで作った Cloud Run、ドメインマッピング、外形監視、プロジェクトの IAM を Terraform に import しました。

Cloud Run の image と labels は ignore_changes にして、デプロイは GitHub Actions に任せています。Terraform で管理するのはサービスの設定だけで、どの image を動かすかは管理しません。

terraform apply も Deploy ワークフローに入れ、apply を終えてから deploy するようにしました。Terraform とワークフローの変更を 1 つの PR にまとめられます。

IAM がシンプルかつ安全になった

変更前 変更後
Cloud Run の実行 SA デフォルトの compute SA(roles/editor) ロールのない専用 SA
レガシー Cloud Build SA roles/run.admin など 3 ロール 不要になったので SA ごと削除
自分のアカウント roles/owner ほか 2 ロール roles/owner のみ

このブログは nginx が静的ファイルを返すだけなので、実行 SA にロールは要りません。

まとめ

デプロイ通知が欲しかっただけなのに、次の 4 つが一度に手に入りました。

  • 通知できるようになった(Cloud Run に移行して以来の悩み)
  • シンプルになった(Cloud Build をやめてほぼ Terraform 管理にし、IAM も整理した)
  • 速くなった(ビルドから反映まで 2 分前後 → 1 分強)
  • Artifact Registry の容量が減った(45.5 GB → 3 GB)

Google Cloud の料金も激減しましたが、それは次回の記事で書こうと思います。

Cloud Run で今回のようなデプロイ通知が欲しい人がどれだけいるか分かりませんが、どなたかの参考になれば幸いです。