Merry Christmas 🎅🎄

というわけで CyberAgent Group SRE Advent Calendar 2025 25 日目(最終日)になります。

株式会社AbemaTV で SRE / Platform Engineer をしている @ren510dev です。今年に入り Google Cloud Professional 認定資格を全冠 しました。

このブログでは、約半年間にわたり実施された ABEMA 広告配信システムの運用基盤および Google Cloud プロジェクト移設の裏側ついて紹介します。

目次

  1. はじめに
  2. 背景
  3. ABEMA 広告配信システム基盤の課題
  4. リアーキテクティングへの踏切
  5. 移行計画とロードマップ
  6. 移設戦略
  7. コミュニケーション計画
  8. おわりに

はじめに

約半年間にわたり、ABEMA の広告配信システムの運用基盤を刷新すべく、Google Cloud Platform の移設プロジェクトを推進しました。

このブログでは、大規模な Google Cloud 環境の移設を完遂するための技術戦略、意思決定プロセスやプロジェクトを動かすためのコミュニケーション計画についてハイライトを紹介できればと思います。

背景

ABEMA の開発体制

まず、ABEMA の開発体制について簡単に紹介しておきます。

ABEMA は、主に「ABEMA 本体のアプリケーションを開発するチーム(以後、ABEMA 本体)」と、「ABEMA へ広告を入稿・配信するシステムを開発するチーム(以後、BD:Business Development)」の 2 つのチームに分かれており、これらを動かす運用基盤(Goolge Cloud)自体も分離されています。

運輸上の課題とプロジェクトの発足

本プロジェクトの背景には、ABEMA 全体で推進されている「運用基盤の継続的な進化」と「基盤の運用・保守業務の組織効率化」という大きなテーマがありました。その一環として広告配信システムにおいても、以下の高い成果目標の達成が求められていました。(一部抜粋)

  • 堅牢なセキュリティ:全社的なセキュリティ基準に準拠した強固な土台を作る
  • 高可用性:大規模イベント時の帯域にも耐え得る運用基盤の拡張性を担保する

しかし、これらの目標を達成する上で、当時の広告配信システム側の Google Cloud 環境におけるプロジェクト構造そのものが、根本的なボトルネックになっていることが判明し、既存環境の延長線上で部分的な改修を行うだけでは、求められるセキュリティ水準やスケーラビリティ要件を満たすことは困難であるという結論に至りました。

ABEMA 広告配信システム基盤の課題

移設前の環境には、構造的な問題が大きく 3 つあり、これらは技術的負債として日々の運用負荷を高める原因となっていました。

環境混在によるセキュリティ統制の複雑化

開発 / ステージング / 本番といった用途が異なる運用環境が混在しており、IAM やネットワークの分離の観点で統一化された運用がなされていない(できない)

ABEMA 本体と広告配信システムとの運用ノウハウの分断

ABEMA 本体で実践している IaC や GitOps、ポリシ管理といった運用ノウハウを広告配信システムの運用基盤に浸透できていない(組織間の共通基盤に能力差分が生じていた)

運用手順の属人化

複雑な構成が常態化し、特定のエンジニアしか詳細を把握していないブラックボックス化が、運用の拡張性や保守の妨げとなっている

リアーキテクティングへの踏切

これらの構造的な課題を解決するために、現状の構成をそのまま移すのではなく、Google Cloud のベストプラクティスに基づいたリアーキテクティングを行う方針を固めました。
具体的には、以下 3 つの戦略を軸に、新しい運用基盤を再設計しました。

環境混在の解消:Google Cloud プロジェクトの分離

開発(DEV)/ 検証(STG)/ 本番(PRD)環境毎に独立した Google Cloud プロジェクトを準備し、リソースを完全に分離します。これにより、「環境混在によるセキュリティ統制の複雑化」を解消し、ネットワークや権限分離を強制することで、開発環境での操作が本番環境へ影響を与えるリスクを排除します。

運用ノウハウの統合:ABEMA 本体標準基盤の採用

独自の基盤構成を廃止し、ABEMA 本体の運用チームが提供する標準基盤(GKE, PipeCD 等)を採用します。これにより、「運用ノウハウの隔離」および「ナレッジの局所化」を解消し、全社的なセキュリティ基準や機能改善を継続的に取り込める体制へと引き上げます。

属人化の排除:IaC と GitOps によるオペレーションのコード化

Terraform によるインフラのコード化(IaC)と、GitOps による SSOT の徹底に加え、運用手順書自体もコードとして管理するフローを導入します。これにより、「運用手順の属人化」や「ブラックボックス化」を解消し、誰が実行しても同じ結果が得られる運用の透明性と再現性を担保します。

移行計画とロードマップ

移設プロジェクトにおいて最大のリスクは、不具合発生時にインフラ起因なのかアプリケーション起因なのかの切り分けが困難になることです。そのため、今回の移設スコープでは機能改修やコードのリファクタリングを最小限に抑え、インフラ基盤の刷新のみに注力することで変更変数を最小化し、トラブルシューティングの複雑さを排除する方針をとりました。

移設作業の指標決め

本戦略の実効性を担保するため、プロジェクトの遂行基準として以下の 2 点を定義しました。

Definition of Done:ゴール・ノンゴールの明確化

移設プロジェクトにおいては、機能改善や細かな修正を同時に行いたくなりますが、これらはプロジェクトの複雑性を高める要因となります。本プロジェクトでは、「新環境への移行」および「旧環境の完全撤去」のみを完了条件とし、それ以外の改善事項は移設後のフェーズへ先送りする方針を徹底しました。目的を「移設」一点に絞ることで、プロジェクトの肥大化を防ぎ、確実な完了を優先しました。

Production Readiness:本番データを用いた並行稼働検証

検証環境と本番環境ではデータセットの規模や特性が異なるため、検証環境でのテストだけでは不十分な場合があります。今回は新旧環境間でデータ同期を確立し、切り替え前に本番データを用いた検証を可能にしました。これにより、クエリパフォーマンスやデータ整合性の問題を、ユーザトラフィックが流れる前に検知・修正する体制を整えました。

移設期間の構成

本プロジェクトでは、環境ごとに独立した Google Cloud プロジェクトを新設し、全社標準に準拠した基盤を構築しました。アーキテクチャの移行方針として、すべてのリソースを物理的に移動させるのではなく、IAM ベースで制御可能な永続データストアは既存プロジェクトに残し、コンピュートリソースや揮発性データストアを新環境へ移行する構成を採用しています。

移行プロセスにおいては、DNS の重み付きルーティングを活用し、ユーザー影響が小さく、かつ切り戻しが容易なコンポーネントから順次トラフィックを切り替える段階的移行(Phased Migration)を実施しました。

以下、ざっくりとしたコンポーネントの移設順序になります。

新規に用意した Google Cloud プロジェクトに GKE とマネージドデータベース(Cloud SQL / Memorystore)を起動させます。
最初の移設フェーズでは IAM での制御が可能なデータストア(Spanner や GCS, Bigtable)は移設を行わず既存のプロジェクトに残留する方針としました。(※ マネージドデータベースの切り替えについては後述します。)

ユーザのトラフィックは DNS の重み付きルーティングで旧環境から新環境に段階的に切り替えます。

GKE の切り替え完了後、Cloud Run や Cloud Run Functions といったサーバレスサービスを移設しました。

移設戦略

各コンポーネントにおける具体的な移行手法について紹介します。

Cloud SQL 移設:DMS レプリケーション

データの移行には Database Migration Service(DMS)を採用し、ダウンタイムを最小限に抑える構成をとりました。

アーキテクチャのポイント

DMS を使うことで、旧 DB と新 DB の間で継続的なレプリケーション(CDC)を維持できます。

  • 事前準備:QA 構築段階で、新環境に Cloud SQL 外部レプリカを作成しておきます
  • データ同期:DMS の Profile/Job を新環境側に準備し、Full Dump から CDC(Change Data Capture)を走らせて同期状態を保ちます
  • 当日作業:移設当日は、旧 DB を Read Only 化して静止点を確保してから DMS を停止し、新 DB を Promote してスタンドアロン化します

Public 経由を採用した理由

当初は PSA(Private Service Access)と VPN を用いたプライベート IP でのレプリケーションも検討しました。しかし、PSA 構成変更時のダウンタイムが許容範囲を超えていたため、今回は Public IP 経由での接続を採用しました。もちろん、DMS 自体の暗号化通信と、Cloud SQL の承認済みネットワーク設定により、セキュリティは担保されています。

Cloud SQL → Cloud SQL の制約

2025 年 6 月時点での DMS の仕様として、Source と Destination の両方を Cloud SQL インスタンスとして構成できない制約がありました。そのため、構成上は `Source=MySQL (on Compute Engine扱い)`, `Destination=Cloud SQL` としてセットアップする必要がありました。こうした事前の検証で発見しにくい制約はスケジュールの遅延要因となるため、早期の検証フェーズ(PoC)で洗い出すことが重要です。

カットオーバーの注意点(Read Only 化)

旧 Cloud SQL を Read Only に設定した際、アプリケーション側が書き込み失敗を検知して Panic や CrashLoop に陥る可能性があります。事前にエラーハンドリングの挙動を確認しておくことが必須でした。

Memorystore 移設:ダブルライト + VPN

キャッシュデータ(Redis)の移行には、アプリケーション側でのダブルライト(Dual-Write)方式を採用しました。

ダブルライトの設計

データロスを防ぐため、移行期間中は新旧両方に書き込む戦略を取りました。

  • 旧ワークロード:旧 Redis(Primary)と新 Redis(Secondary)の両方に Write を行います
  • 新ワークロード:新 Redis にのみ Write / Read を行います
  • 接続経路:旧環境から新環境の Redis への接続は、VPN を経由してプライベート接続を確保しました

例外:Routes-based GKE Cluster の接続

旧環境の一部に残っていた Routes-based GKE Cluster(Deprecated)では、Pod CIDR の制約により Memorystore へ直接ルーティングできない問題が発生しました。これに対しては、TCP Proxy(HAProxy)を介する方式で回避しました。こうした例外対応は、必ず手順書に残し、将来的に標準構成へ戻すための計画もセットで管理しました。

Cloud Run 移設:クロスプロジェクト通信の実現

Serverless リソース(Cloud Run)の移行においては、VPC 外から新環境の Cloud SQL(Private IP)へ安全に接続する経路設計が課題となりました。
解決策として Direct VPC Egress を採用し、Cloud VPN で接続されたプロジェクト間のバックボーンネットワークを経由させることで、パブリックネットワークを通さずにセキュアなクロスプロジェクト通信を実現しました。

これにより、アプリケーションのエンドポイント変更のみで、既存のネットワーク構成を維持したままスムーズな移行が可能となりました。

ロールバックは「比率を戻す」を原則化

万が一、エラー率の上昇や Crash の兆候が見られた場合のルールを単純化しました。「原因調査をしてから直す」のではなく、「まず WRR の比率を旧 100 に戻す」ことを最優先としました。切り戻し用の Pull Request をマージする方式も検討しましたが、緊急時のリードタイムをゼロにするため、DNS ポリシ変更での対応を採用しました。

コミュニケーション計画

移設プロジェクトの進行を妨げる要因の多くは、技術的な問題よりも、チーム間の認識齟齬や意思決定の遅れにあります。特に複数チームが連携する場合、情報の非対称性は致命的な手戻りを引き起こしかねません。そこで本プロジェクトでは、円滑なコラボレーションを実現するためのコミュニケーション設計に注力し、以下の 4 点を運用ルールとして定めました。

誰が何を決めるか(責務分解)

大規模なプロジェクトでは、担当領域の境界でタスクの抜け漏れが発生しがちです。特にインフラとアプリケーションの接点(DB 接続設定やデプロイパイプライン等)は責任の所在が曖昧になりやすいため、チーム間の責務を明確に定義し、ドキュメントとして合意形成を行いました。

プラットフォームチーム

新プロジェクトの準備、GKE 構築、CI/CD 導入、DB 移設、監視設定などを担当します。アプリケーションが稼働するために必要な基盤環境を提供し、可用性とセキュリティに対して責任を持つ体制としました。

アプリケーション開発者

アプリケーションの改修、QA 実施、データ二重書き込みの実装、Cloud Run/Functions の移設を担当します。ビジネスロジックへの影響を最小限に抑え、データ整合性とアプリケーションの挙動に対して責任を持つ役割定義を行いました。

事前に役割分担と権限付与を完了させておくことで、移設当日の作業遅延リスクを排除しました。

情報集約場所の定義

情報は管理しなければ分散してしまいます。チャットツール、口頭での会話、個人のメモなど、情報が分散するほど、メンバー間の認識にズレが生じます。認識齟齬を防ぎ、全員が同じ情報を参照できるように、情報の種類ごとに参照すべき場所(Single Source of Truth)を定義しました。

進捗/タスク管理(GitHub Projects)

日々のタスクはすべてここでチケット化し、カンバン形式で管理しました。各タスクの担当者と進捗状況を可視化し、デイリースクラムでの状況確認のベースとしました。

手順/チェックリスト(移設手順書 / Esa)

全体概要から各コンポーネント(GKE, Cloud Run, Cloud SQL)の手順まで、すべてドキュメント化しました。手順書には具体的なコマンドと期待される出力結果まで記載し、作業者による手順のバラつきを排除しました。

議論/論点整理(FigJam)

複雑な構成図やフローチャートを用いて、認識合わせを行う場として活用しました。図解しながら議論することで、テキストだけでは伝わりにくい構造的な課題を可視化し、解決につなげました。

会議体の設計(効率化)

会議は情報共有のために必要ですが、多すぎると開発者の生産性を下げてしまいます。PM としては、会議の開催自体を目的にせず、意思決定とプロジェクト推進を目的に会議体を設計しました。
定例会議は最小限に抑えつつ、目的を明確に定義しました。

週次定例

進捗確認だけでなく、タスク間の依存関係の整理や、リスクの棚卸しを行う場としました。ここで課題を早期に発見し、次のアクションを確定させることに集中しました。

移設前リハーサル

本番想定で手順書の読み合わせを行いました。各コマンドの実行所要時間や、エラー発生時の対応フローをシミュレーションし、手順書の不備を洗い出しました。

当日体制の固定

移設当日は、オペレーション担当、監視担当、記録担当、連絡担当といった役割を固定し、機能的な体制を組みました。

直後の振り返り

各環境(Dev/Stg)の移設直後に振り返りを行い、改善点を洗い出しました。ここでの気づきを次環境である本番環境(Prd)の手順書に即座に反映することで、移設の精度を高めていきました。

単独判断を排除する運用の構築

「単独判断禁止」というルールを徹底するためには、個人の判断に頼らない仕組み作りが必要でした。焦りや確認の手間から生じる独断を防ぐため、判断の余地をなくす準備を行いました。

チェックリストの具体化

手順書には、「確認する」という曖昧な表現を避け、「コマンドを実行し、ステータスが Running であることを確認する」といった具体的かつ定量的な記述を徹底しました。これにより、作業者の主観が入る余地を排除しました。

例外対応の事前定義(If-Then Rules)

エラー率の上昇など、その場で判断が必要になるケースを事前にシミュレーションし、例外対応フローとして定義しておきました。

ロールバック手順の確立

「戻す」という判断を迅速に行えるよう、手順を確立しました。WRR の比率変更コマンドをすぐに実行できる状態で待機しておくことで、問題発生時に即座に切り戻しを行える体制を整えました。

おわりに

本記事では、ABEMA 広告配信システムの Google Cloud プロジェクト移設について、リアーキテクティング戦略から具体的な技術実装、そしてプロジェクトを推進するためのコミュニケーション設計までを紹介しました。技術面では、Google Cloud プロジェクトの完全分離や IaC / GitOps の徹底により、セキュリティと運用効率を大幅に向上させることができました。また、移行プロセスにおいては、DNS を活用した段階的な切り替えやデータ同期技術を駆使することで、サービスへの影響を最小限に抑えた安全な移行を実現しました。

一方で、こうした大規模な移行を完遂するためには、技術的なアプローチだけでなく、関係者間の責務定義や合意形成といったプロジェクトマネジメントの要素も不可欠でした。