Language: 日本語
「手元で動かして確認」をなくす。PR ごとに実アプリを触れる Preview QA 環境を Cloud Run で作った話
Pull Request のレビューをするとき、**「コードの差分は良さそうだけど、実際の画面を触って操作感やレイアウトを確かめたいな……」** と思うことはありませんか?
Pull Request のレビューをするとき、「コードの差分は良さそうだけど、実際の画面を触って操作感やレイアウトを確かめたいな……」 と思うことはありませんか?
しかし、いざ手元で動かそうとすると、
- ブランチをローカルに checkout する
.envや環境変数を整える- Docker コンテナを起動し、DB マイグレーションとシードデータを流し込む
- ローカルサーバーを立ち上げてブラウザでアクセスする
……と、確認を始めるまでに 10〜15 分近くかかってしまい、レビューの心理的ハードルが跳ね上がってしまいます。
かといって、「一旦 dev 環境にマージしてから確認しよう」としていては、マージ前に動作確認してバグを防ぎたいという本来の目的と完全に矛盾 してしまいます。
そこで、PR を作成すると 数分で実際の動くアプリ(Preview URL)が自動生成され、PR のコメントに届く「Preview QA 基盤」 を Google Cloud Run 上に構築しました。
この記事では、インフラコストを最小限に抑える Cloud Run のタグ付きリビジョン(Tagged Revision)活用術 と、差分に応じた Lite / Full の使い分け、そして Trusted Workflow によるセキュリティ設計 を解説します。
得られること
- Cloud Run のタグ付きリビジョン(
--no-traffic)を活用し、サービスを増やさずに PR 専用プレビュー URL を発行する仕組みがわかる - 変更内容に応じて「Lite(アプリのみ・dev DB 共有)」と「Full(専用 DB / migration)」を切り替える賢いコスト・速度設計が学べる
- fork PR や悪意あるコードから Secret を保護する Trusted Workflow(実行権限制御)の境界設計が身につく!
Preview QA の全体フロー
PR が作られてから、実際に触れる URL がコメントに返るまでのフローは以下のようになっています。
PR 作成 / push (または /qa-deploy コメント)
↓
【 Trusted Workflow 】
・実行者の権限を確認(write 権限 or same-repo)
・CI のツールやデプロイスクリプトは「信頼できる default branch」から取得
・アプリケーションのソースコードだけ「PR HEAD」から取得
↓
【 Build / Push 】
・PR のソースコードから frontend / backend のコンテナイメージをビルド
↓
【 Cloud Run へデプロイ(差分に合わせて分岐)】
├─ [ Lite QA ] dev DB を共有し、tagged revision を --no-traffic で作成 ⚡️
└─ [ Full QA ] ブランチ専用 DB を作成し、Migration Job を実行してから起動 ⚡️
↓
【 共有ロードバランサ (Wildcard URL) 】
・https://pr-123---app-service.example.com で特定リビジョンへルーティング
↓
【 GitHub PR コメントへ Preview URL を通知 🎉 】
Cloud Run のタグ付きリビジョンによる超軽量デプロイ
PR ごとにプレビュー環境を用意しようとすると、「PR の数だけ Cloud Run サービスを丸ごと Terraform で新設するのか?」と考えがちです。しかし、サービスを乱立させると IAM 設定、ロードバランサの再構成、URL 発行のオーバーヘッドが膨大になります。
そこで活用したのが、Cloud Run の タグ付きリビジョン(--tag)機能 です。
# 既存の dev サービスに対して、PR 専用のタグを付けてデプロイ
gcloud run deploy dev-backend-service \
--image="${IMAGE_URI}" \
--tag="pr-${PR_NUMBER}" \
--no-traffic \
--region=asia-northeast1
この構成の美しさ
- 既存の通常トラフィックに一切影響しない:
--no-trafficでデプロイするため、dev 環境のメイン URL(100% トラフィック)は何も変わりません。 - 一意のプレビュー URL が即座に手に入る:
Cloud Run はタグを付与すると、自動的に
https://pr-123---dev-backend-service-xxx.a.run.appというタグ専用の固有 URL を払い出します。 - 共有ロードバランサとの連携:
共有ロードバランサにワイルドカード DNS(
*.preview.example.com)を設定しておくことで、社内独自ドメインの綺麗な URL で即座にアクセスできます。
差分に合わせて作る: Lite と Full の使い分け
当初はすべての PR で同じフルセットの環境を作ろうとしていました。 しかし、CSS やちょっとしたボタンの修正といった「DB スキーマを一切触らない PR」のために、毎回ブランチ専用の DB をプロビジョニングしてマイグレーションを走らせるのは時間もコストも無駄です。
そこで、変更差分に応じて Lite と Full の 2 つのモードを用意しました。
| 項目 | Lite QA | Full QA |
|---|---|---|
| 対象差分 | フロントエンド / バックエンドのアプリコードのみ | DB スキーマ変更・Migration を含む差分 |
| Cloud Run | tagged revision(--no-traffic) | tagged revision(--no-traffic) |
| DB / Secret | dev 環境の DB / Secret をそのまま共有 ⚡️ | ブランチ専用 DB / Secret を作成 🔒 |
| Migration | なし(不要) | Cloud Run Job で事前に migration を実行 |
| 起動トリガー | same-repo PR の自動 gate または /qa-deploy | コメント /qa-deploy で明示実行 |
| 完了時間 | 約 2〜3 分で即時完了 | 約 5〜6 分 |
- Lite: dev DB をそのまま共有するため、わずか 2〜3 分でコンテナのタグ付きデプロイが終わり、爆速で Preview URL が届きます。
- Full: スキーマ変更がある場合のみ、共有の Cloud SQL インスタンス内にブランチ専用の論理 DB(
qa_pr_123)を作成し、Cloud Run Job でマイグレーションを流してから起動します。
Trusted Workflow によるセキュリティ防壁
プレビュー環境を構築する上で最も注意しなければならないのが 「PR のコードをクラウド上で実際に実行する」というセキュリティリスク です。
悪意のあるサードパーティが fork から PR を出し、GitHub Actions の workflow ファイルを書き換えてクラウドのデプロイ権限や Secret を外部に送信する攻撃(いわゆる Poisoned Pipeline Execution)を防ぐ必要があります。
そのため、以下の Trusted Workflow 境界 を厳格に設計しました。
【 実行権限の分離 】
1. same-repo かつ write 権限を持つメンバーの PR のみ自動起動を許可
(fork からの PR や外部コントリビューターは maintainer の /qa-deploy 承認が必須)
2. workflow 定義とデプロイスクリプトは「default branch (main)」のものを強制使用
(PR 側で .github/workflows や deploy スクリプトを改ざんしても一切反映されない)
3. PR からチェックアウトするのは「アプリのソースコード(コンテナビルド対象)」のみ!
この境界を敷くことで、開発者の利便性を最大限に保ちながら、悪意あるコードによるクラウド権限の奪取を構造的に遮断しています。
リソースの自動 Cleanup(お掃除の自動化)
作った環境は、使い終わったら綺麗に消さなければクラウドコストが膨らみ続けます。
- PR がクローズされたとき(merge / close): GitHub Actions がトリガーされ、Cloud Run のタグ、リビジョン、ブランチ専用 DB、Secret を全自動で削除。
- 明示的な破棄: PR に
/qa-destroyとコメントすることでも即座にクリーンアップ可能。
作る仕組み(Deploy)は動かないと全員が困るのですぐ直されますが、消す仕組み(Cleanup)は失敗しても誰も困らないため、放置されてコストの山になりがち です。
そのため、GitHub Actions の定期スケジュール(cron)で「すでに Close された PR のゴミが残っていないか」を走査して掃除する直列スイーパー(Sweeper)も併せて稼働させています。
レビュー体験の変化
Preview QA を導入したことで、開発チームのレビュー体験は一変しました。
レビュアーはローカルで環境を作る必要が一切なくなり、PR に届いた URL をブラウザでポチッと開くだけで、実際の画面やアニメーション、API との連携をその場で確認 できます。
特にデザイナーやプロダクトマネージャー(PO)といった非エンジニアのメンバーも、マージ前に実際の UI を触ってフィードバックを出せるようになったのは感動的な変化でした。
「手元で動かす手間」をゼロにし、レビューの回転速度を極限まで高める Preview QA 基盤。Cloud Run のタグ付きリビジョンを使えば驚くほど低コストかつ軽量に構築できるので、ぜひ試してみてください!