はじめに ─ 長く更新が止まっていたインフラを引き継ぐ
対象は、VR 向けの動画配信サービスです。管理画面でコンテンツを登録し、インストール型の VR 再生クライアントと API から配信する構成で、動画の実体は 約 1.7TB・3,200 本超。基盤は CentOS 7 / PHP 7.2 / CakePHP 3.6 / MySQL 5.7 ── いずれもサポートが終了(EOL)した構成のまま動いており、OS も言語もフレームワークも長く更新されていないことが、ひと目で分かる状態でした。
一方で動画ファイルだけは増え続け、EBS は 2TB まで拡張され、その約 1.7TB が動画で占められています。データ量が大きいこともあってか、バックアップは運用されていませんでした。さらに RDS の MySQL もバージョンが上がっておらず、標準サポートの切れた 5.7 を使い続けるための 延命料(Extended Support)が、毎月まとまった額として積み上がっていました。
本記事は、こうした長く更新が止まっていたインフラを、コストを抑えながら、無理なく運用できる水準までアップデートしていく過程をまとめたものです。脱 EOL と安定化、そしてコスト削減を、一つの構成変更でまとめて進めます。次章ではまず、その費用の中身を請求書から読み解いていきます。
本記事の削減額・月額は 試算(見込み)です。確定値はカットオーバーとストレージ階層の最適化・旧リソース削除を終えた実績で更新します。顧客名・ドメイン・バケット名・IP 等の固有情報は伏せています。
1. 請求書を分解する ─ 3 つの無駄を特定
まずは実物を見てもらうのが早いです。これは 2026 年 4 月の請求(サービス別料金)のスクリーンショットです。課税前 $1,305.58、税込 $1,436.14(¥160/$ 換算で 約 23 万円)。

ただ、このサービス名(名目)だけ見ても、「何の転送なのか」「なぜデータベースにこれだけかかるのか」までは分かりません。各費目の中身を辿ると、削るべき 3 つの無駄がはっきりしました。
① 配信 egress(Data Transfer)
$560 / 月・請求の 4 割超EC2 から利用者へ動画を直接配信していたため、転送料が突出。最大の費目(本丸)。
配信を 低単価 CDN(Bunny.net)へ移して転送費を圧縮し、オリジン取得は CloudFront の無料枠(月 1TB)で吸収する。
② RDS の延命料(Extended Support)
$367 / 月(うち延命料 約 $229)MySQL 5.7 のサポート終了後の延命料が大半。冗長化も使っておらず、DB 本来の処理に見合わない。
DB を EC2 に同居させ、RDS は廃止する。
③ EBS ストレージ(EC2 に同梱)
EC2 $366 / 月に同梱・EBS 2TB2TB の EBS(90% 使用・容量枯渇間近)に 1.7TB の動画が載っていた。インスタンス費とまとめて EC2 に計上されている。
動画ファイルは S3 で運用し、EBS は最低限の大きさに抑える。
2. EC2(Amazon Linux 2023)にて VR 動画サービスを複製&改修
コスト削減を急いで本番に手を入れるのは危険です。そこで 旧本番には一切手を加えず、新しい EC2 に VR 動画サービスを丸ごと複製してから、新環境側で改修・検証していく進め方にしました。新旧が並走するので、問題があればいつでも旧へ戻せます(止めない・壊さない)。全体は次の 3 弾構成で、本章はその 第 1 弾 ── 基盤の複製と改修です。
- 第 1 弾(本章・基盤刷新):新 EC2(Amazon Linux 2023 / Graviton)へシステムを複製し、PHP / CakePHP / DB を刷新して EOL を一掃。
- 第 2 弾(配信最適化):動画・画像を S3 へオフロードし、CDN で配信(第 3 章以降)。
- 第 3 弾(切替・撤去):Elastic IP の付け替えで本番切替 → 数日監視 → 旧 EC2 / RDS / 余剰 EBS を削除して削減を確定。
新サーバーを Graviton + Amazon Linux 2023 で立てる
新サーバーは Amazon Linux 2023、CPU は Graviton(ARM / t4g)。旧世代の t2.small から、低単価で効率の良いインスタンスへ置き換えます。swap を確保し、ミドルウェアは nginx / PHP 8.2 / MariaDB 11.4 を導入。OS から言語・フレームワークまで、EOL だった構成を現行サポート版へ一気に引き上げました。
DB は RDS から複製し、EC2 同居のローカル MariaDB へ
データベースは RDS から全 DB を複製し、新 EC2 に同居させた ローカル MariaDB へ移しました。移行後は 全テーブルの行数を新旧で照合して一致を確認し、文字コードを utf8mb4 へ昇格。日次バックアップ + 復元テストも整備しています。
RDS を廃止できたのは、元々 Multi-AZ などのマネージド HA を使っておらず、本番 DB の実データも数 MB 規模だったため。冗長機能が活きていない RDS に延命料まで払う状態を、ローカル DB へ畳みました。失う自動バックアップ/PITR は上記の自前バックアップで代替しています(着手前はバックアップ自体が止まっていたため、むしろ復旧体制の再建にもなりました)。
アプリを CakePHP 3.6 → 4.6 / PHP 7.2 → 8.2 へ改修
複製したアプリは、CakePHP 3.6 → 4.6・PHP 7.2 → 8.2 という大型バージョンアップ。破壊的変更(テンプレート構成・認証・ルーティング・ORM / Query API・エラーハンドラ・画像処理など)を段階的に解消しました。API 認証(JWT)は、サポートの切れた旧プラグインを firebase/php-jwt + 自作アダプタへ置き換え。ここで肝心なのは、API の URL とレスポンスは一切変えていないこと ── 更新できない VR 再生クライアントに影響を出さないためです。
URL / API 契約は一切変えない
最大の制約は、インストール済みで更新できない VR 再生クライアントが参照する …/upload/… の URL と API レスポンスを 変えられないことでした。そこで 配信先の振り分けはサーバー内部(nginx)で行い、アプリが返す URL は据え置きに。これにより クライアントに影響を与えずに配信先を差し替えられる状態を作っています。この「疎結合にしておいた」判断が、のちの配信先の入れ替え(第 3 章以降)を無改修で可能にしました。
3. 配信先を 3 回変えた ─ S3+CloudFront → R2 見送り → Bunny.net
配信費(egress)が最大要因 ── これを下げにいったのですが、ここからが本件の試行錯誤でした。配信先は結果的に 3 回変わっています。
CDN を入れたのに、配信費が下がらなかった
まず素直に S3 + CloudFront で CDN 化しました。これ自体に効果はあって、動画を S3 へ逃がしたぶん EBS を縮小でき、配信も CloudFront の無料枠(月 1TB)のぶんは egress が無料になります。
ただし問題は規模でした。このサービスの配信 egress は月 4TB 超で、無料枠 1TB を大きく超過します。超過分の 日本(Asia Pacific)向け CloudFront egress 単価は約 $0.114/GB ── EC2 直配信とほぼ同額。キャッシュでオリジンへの往復は減っても、利用者へ届ける配信 egress 自体は同じだけ課金されます。
つまり、EBS と無料枠ぶんは削れたものの、本丸(配信 egress)の削減は限定的。配信費を本当に下げるには、egress 単価そのものが低い配信先を別に探す必要がありました。
egress 無料に惹かれ、検証まで進めたが規約で止めた
次に目を付けたのが Cloudflare R2。egress が無料(保管量と操作回数のみ課金)で、S3 互換 API を持つため、アプリの保存実装はエンドポイントの差し替えで済みます。実際に 移行 → 再生の E2E 検証まで完了しました(Range リクエストでの部分取得、日本語ファイル名の保持まで確認)。
しかし本番化の前に規約を読み込むと、Self-Serve の規約に、動画など非 HTML コンテンツの不釣り合いな大量配信を別契約なしで行うことを制限する条項がありました。4TB/月規模の動画を恒常的に乗せてよいかの解釈はグレー。サポートに照会しても「違反」とも「問題ない」とも明言は得られませんでした。
明言が得られないこと自体がリスクと捉え、本番採用は見送り。egress 無料という目先のメリットより、配信が止まる事業リスクを避ける判断です。規約のグレーは本番前に潰す ── これが二つ目の学びでした。なお、R2 で作った検証資産(所有判定・Range 配信検証・転送手順)は次の選択肢へそのまま流用できました。
動画配信を規約上明確に許可し、転送単価が低い CDN へ
最終的に Bunny.net を選びました。決め手は次のとおりです。
- 動画配信を規約上明確に許可している(R2 で引っかかった点がクリア)。
- 転送単価が非常に低い(最安の Volume Network は $0.005/GB・全世界単一レート)。
- 永続保存(Perma-Cache)に対応し、オリジンへの再取得を最小化できる。
- カスタムドメイン不要・DNS 変更不要で導入でき、移行リスクが小さい。
4. 最終構成 ─ Bunny × オリジン=CloudFront × Perma-Cache
辿り着いたのは、役割を明確に分けた 3 層構成です。一見すると遠回りに見える「Bunny のオリジンに CloudFront を挟む」形に、二つの利点があります。
[利用者 / VR アプリ]
│ https://…/upload/…(従来どおりの URL)
▼
[Bunny.net CDN] … 利用者への配信。低単価・Perma-Cache で永続保存
│ (Bunny に無い場合のみ取得)
▼
[Amazon CloudFront] … 取得の窓口。AWS 無料枠(月 1TB)でほぼ $0
│
▼
[Amazon S3] … 動画/画像の唯一の正(永続保存の本体)3 つの層の役割
| 層 | 役割 |
|---|---|
| S3 = 保存の正 | アプリのアップロード先。唯一の永続保存。ここだけが「正」のデータ |
| CloudFront = 取得の窓口 | Bunny が S3 から取得する経路。AWS 無料枠 月 1TB に収まりほぼ $0 |
| Bunny.net = 利用者への配信 | 低単価 egress で配信。取得した動画は Perma-Cache に永続保存 |
動作(探索順)
利用者のリクエストは、上から順に探索されます。
- Bunny エッジに HIT すれば即配信。
- MISS でも Perma-Cache にあればそこから配信。
- どちらにも無ければ CloudFront 経由で S3 から取得し、取得したものを Perma-Cache へ永続保存。以降このファイルはオリジンへ取りに行かない(取得は原則 1 回)。
なぜ S3 + CloudFront を併用するのか
配信そのものは Bunny に任せます。正直なところ、Bunny.net だけで完結させた方が構成はシンプルです。それでも裏側(オリジン)に S3 と CloudFront を残して併用しているのは、動画の正本を AWS 側(S3)に持っておく方が、バックアップとして信頼できると考えたからです。S3 を唯一の永続保存(正)とし、Bunny や CloudFront はあくまで使い捨てのキャッシュ ── データの拠り所を S3 ひとつに集約しておけば、キャッシュが消えても S3 から作り直せます。
ただし S3 を直接インターネットへ公開するのは避けたい(意図しないアクセスや余分な egress 課金を防ぐため)。そこで S3 はパブリックアクセスを閉じたまま、CloudFront だけが取得できる窓口にしました。保存は S3・取り出しは CloudFront と役割が分かれ、しかも CloudFront には AWS 無料枠(月 1TB)が使えます。この S3 + CloudFront のセットは、Bunny.net で障害が発生した際に nginx の設定を切り替えることで、そのまま 全動画を保持したフォールバック経路にもなります。
なぜオリジンを S3 直ではなく CloudFront にするのか
ここが構成の肝です。Bunny のオリジンに CloudFront を挟むことで、二つの利点が生まれます。
取得コストが実質ゼロ
Bunny がオリジンから取得する通信を CloudFront 無料枠(月 1TB)で吸収。Perma-Cache のおかげで各ファイルの取得は原則 1 回なので、取得トラフィックは無料枠に収まり、ほぼ $0 で済みます。
切替先が常に検証され続ける
平常時も Bunny→CloudFront→S3 の取得が日々動くため、障害時の切替先(CloudFront 直配信)が実トラフィックで検証され続けます。「いざ切り替えたら動かない」を構造的に防げます。
Bunny.net の設定
| 項目 | 設定 |
|---|---|
| Pull Zone | Volume Network(最安・10 PoPs・全世界単一レート $0.005/GB)を選択 |
| レプリケーション | 無し(シンガポール単一リージョン・複製ゼロでコスト最小) |
| オリジン | CloudFront の URL(https://xxxxxxxx.cloudfront.net) |
| Perma-Cache | 有効 |
オリジンに CloudFront を指定する際は、Host ヘッダを配信ドメインに一致させるのが要点です(不一致だと CloudFront が 403 を返します)。
5. 動作確認(E2E)─ 760MB 動画で MISS→pull→HIT を実機確認
構成を組んだら、実データで端から端まで通します。あえて条件が厳しめのファイル ── まだ一度も取得されていない、日本語名 + スペース入りの 760MB 動画 ── を選び、探索のすべての分岐を 1 回で踏ませました。
| 確認した挙動 | 結果 |
|---|---|
| 初回アクセス(未取得) | MISS → CloudFront pull → S3 取得 → 200 OK |
| 途中再生(シーク) | Range リクエストに 206 Partial Content / 正しい Content-Range |
| 再アクセス | HIT(Bunny から直接配信) |
| 永続化 | Perma-Cache に実体が生成されたことを確認 |
| 日本語名 + スペース | URL エンコードの懸念も含め正常に配信 |
MISS → pull → 200、Range → 206、再アクセスで HIT、そして Perma-Cache の実体生成まで一気通貫で確認できました。シーク再生に必須の部分取得(206)が効くこと、日本語ファイル名でも破綻しないことが分かり、本番投入の前提が揃ったことになります。
__bcdn_perma_cache__/… 配下)や配信時の HIT/MISS で判断するのが正確です。6. コスト試算 ─ 通信費の圧縮で月額を大幅削減
ここまでの構成変更を積み上げると、月額の見込みは次のようになります。「従来」は 2026 年 4 月の実請求、「新構成」は月 4TB 配信を前提とした試算です(¥160/$ 換算。実費はトラフィックで変動します)。
| 項目 | 従来 | 新構成 |
|---|---|---|
| 動画配信(転送 / egress) | Data Transfer $560(約 ¥9.0 万) | 約 ¥5,000/月(Bunny Volume Network $0.005/GB・約 90% 削減) |
| Bunny ストレージ | ─ | 約 ¥2,500/月(1.7TB・シンガポール単一) |
| CloudFront | ─ | ほぼ ¥0(無料枠 月 1TB で吸収) |
| S3 保存 | (旧 EBS に同梱) | 約 ¥3,600/月(Infrequent Access 想定) |
| RDS(データベース) | $367(延命料 $229 込み・約 ¥5.9 万) | 廃止(ローカル MariaDB へ) |
| EC2(サーバー) | t2.small + EBS $366(約 ¥5.9 万) | Graviton(t4g)へ刷新 |
| その他(CW / VPC / Route 53 / 税) | 約 ¥2.3 万 | 微少 |
| 合計 | 税込 約 ¥23 万(2026年4月) | 月 2 万円以内(試算) |
金額が下がる最大の理由は、単価そのものの差です。とくに 配信 egress と 保管は、配信元・保管先を変えるだけで GB あたりの単価が桁で変わります(いずれも目安)。
| 単価(目安) | 従来 | 新構成 |
|---|---|---|
| 配信 egress(転送) | CloudFront / EC2 直 ≈ $0.114/GB(東京) | Bunny Volume Network ≈ $0.005/GB(全世界単一レート)── CloudFront の 約 1/20 |
| ストレージ保管 | EBS gp2 ≈ $0.12/GB・月 | S3(IA)≈ $0.014/GB・月 / Bunny 保管 ≈ $0.01/GB・月 |
※ RDS の延命料(Extended Support・月およそ $229)と旧世代 EC2 は、単価ではなく 廃止・刷新で削っています。
着地点:月額を大幅圧縮 ── 2 万円以内の見込み(試算)
2026 年 4 月の AWS 費用は税込 $1,436(¥160/$ 換算で 約 23 万円、課税前で約 21 万円)。これが上記の積み上げで 月 2 万円以内に収まる試算になりました。削減率にして約 9 割、年間では 100 万円規模の圧縮が見込めます。
内訳の核は、① 配信 egress を低単価 CDN へ移して約 90% 削減、② RDS の延命料を廃止、③ 旧世代 EC2 を Graviton へ刷新の 3 つです。確定値は、本番切替・S3 階層最適化・旧リソース削除の完了後に更新します。
7. 運用の形 ─ アップロード / 更新 / 削除 / バックアップ
コストと並んでもう一つの着地点が、日常運用が無理なく回る形にまとまったことです。アップロードから削除まで、それぞれが自動で完結します。
| 操作 | 流れ |
|---|---|
| 新規アップロード | アプリ → S3。初回アクセス時に Bunny が自動取得・永続化(事前の一括コピー不要) |
| 更新(差し替え) | 新規登録して参照を切替。動画は固定の一意パスで管理し上書きしないため、新パスになり古いキャッシュと衝突しない(パージ不要) |
| 削除 | アプリ削除で S3 削除 + Bunny の該当ファイルを URL 単位でパージ。取りこぼしは整理バッチで回収 |
| ウォームアップ | サイト巡回でサムネ、再生で動画が Bunny に蓄積(自動。本切替前のまとめ温めも可) |
| SSL 証明書 | ワイルドカード証明書を年数回・手動更新(新サーバー単独で更新できるよう整備済み) |
| バックアップ | DB は日次取得。動画の正本は S3(将来は長期保管層へ退避し原本保全) |
削除時のパージには 安全装置を入れています。認証情報が未設定なら無動作(no-op)、パージに失敗してもログを残すだけで 削除本体は止めません。取りこぼしは整理バッチで回収できるため、配信の更新・削除フローが運用で破綻しないようにしています。
8. フェイルオーバーと即ロールバック
- CDN(Bunny)障害時:サーバー設定の変更 1 箇所で、配信先を Bunny → CloudFront 直へ即時切替。CloudFront + S3 は全コンテンツを保持しているため、全動画の配信を途切れさせずに継続できます。戻しも即時。
- 切替先は常時検証済み:前述のとおり、平常時も Bunny は CloudFront 経由で取得しているため、フェイルオーバー先が日々の実トラフィックで動作確認され続けています。
- データ消失リスクなし:永続保存は S3 のみが正で、CloudFront / Bunny は使い捨てキャッシュ。消えても/消しても S3 から再生成されます。
- サーバー切替:本番サーバーの切替・切戻しは Elastic IP の付け替えのみ。DNS 変更を伴わず、即時ロールバックできます。
「安く配信する」だけでなく、止まらない・戻せる・消えないを構成の中に織り込んだことで、コスト削減と安定性を同時に成立させています。
9. 学び・はまりどころ
- 請求書は分解してから読む:名目(サービス別合計)では削りどころは見えない。各費目の中身(何の転送か / 何にかかる DB 費か)まで辿って初めて、転送・保管・延命料という輪郭が出る。
- CDN を入れれば自動でコストが下がるわけではない:キャッシュはオリジン往復を減らすが、利用者への配信 egress は CDN からも課金される。単価構造を見て「本丸が動くか」を確かめる。
- 規約のグレーは本番前に潰す:egress 無料などの目先のメリットがあっても、サポートが可否を明言しない状態は事業リスク。検証が通っても規約で止める判断はあり得る。
- オリジンに無料枠を挟む利点は二つ:Bunny のオリジンを CloudFront にすると、取得を無料枠で吸収しつつ、切替先を常時検証できる。
- URL を疎結合にしておくと差し替えが効く:配信先をアプリの URL に直書きせず、サーバー内部の振り分けにしておいたことで、配信基盤を入れ替えても無改修で済んだ。
- 長時間バッチはセッション切断で死ぬ:1.7TB 同期のような長時間処理は、SSH セッションが切れた瞬間に OS 側でプロセスごと掃除されることがある。リンガー有効化や systemd ユニット化で恒久化する(同期は冪等なら再開できる)。
- キャッシュは「上書きしない設計」で事故を防ぐ:固定の一意パスで管理し差し替えを新パスにすると、パージ不要で更新が反映され、キャッシュ運用の事故が起きにくい。
あとがき
この事例の根っこにあるのは、請求書の中身を分解し、本当の無駄を見つけて、止めずに移すという地道な作業です。動画配信のように配信 egress が支配的なサービスでは、CDN を入れるだけでは費用は下がりません。単価構造を見て、配信先そのものを選び直すところまで踏み込んで、初めて AWS 費用を 2 万円以内に収める試算になりました(2026 年 4 月実績ベースで約 9 割の圧縮)。
同時に、EOL の一掃・容量枯渇の根治・バックアップ体制の再建・即ロールバック可能な切替設計まで一度に整えています。コスト削減と安定化は、別々ではなく一つの設計で同時に達成できます。AWS の運用コスト診断・設計レビューのご相談は、AWS コスト分析ツール から、または info@moobon.jp までお気軽にどうぞ。
本記事の金額は試算です。本番切替・ストレージ階層の最適化・旧リソース削除の完了後に、確定値で更新する予定です。
よくある質問
QCDN(CloudFront)を入れれば動画の配信費は下がるのではないですか?
キャッシュが効くぶんオリジン(S3 や EC2)への往復は減りますが、利用者へ届ける最後の配信(egress)自体は CDN からも従量課金されます。日本(Asia Pacific)向け CloudFront の egress 単価は EC2 直配信とほぼ同じ水準のため、配信費が最大要因のサービスでは『CDN を入れたのに下がらない』が起こり得ます。本事例ではここが出発点になりました。
Qなぜ Cloudflare R2 を採用しなかったのですか?
R2 は egress 無料が魅力で、移行と再生の E2E 検証まで進めました。ただし Self-Serve の規約に、動画など非 HTML コンテンツの大量配信を別契約なしで行うことを制限する条項があり、4TB/月規模の動画を本番で恒常的に乗せてよいかの解釈がグレーでした。サポートに照会しても明確な可否が得られなかったため、事業リスクと判断して本番採用は見送り、動画配信を規約上明確に許可しているサービスを選びました。規約の確認は本番前に済ませる、というのが学びです。
QBunny.net のオリジンを S3 ではなく CloudFront にしているのはなぜですか?
二つ理由があります。一つは、Bunny がオリジンから取得する経路を AWS の CloudFront 無料枠(月 1TB)に収め、取得コストを実質ゼロにできること。もう一つは、平常時も Bunny→CloudFront→S3 の取得が日々動くため、障害時の切替先(CloudFront 直配信)が実トラフィックで常に検証され続けることです。『いざ切り替えたら動かない』を避けられます。
QPerma-Cache は通常の CDN キャッシュと何が違いますか?
通常のエッジキャッシュは有効期限やアクセス頻度で消えますが、Perma-Cache は一度取得したファイルをストレージに永続保存します。これにより各ファイルのオリジン取得は原則 1 回で済み、以降はオリジン(CloudFront/S3)へ取りに行きません。大容量の動画を繰り返し配信するワークロードで、オリジン側の負荷とコストを最小化できます。
QRDS を廃止してローカル DB にして大丈夫なのですか?
対象サービスはもともと Multi-AZ などのマネージド HA を使っておらず、本番 DB の実データも数 MB 規模でした。RDS の冗長機能が活きていなかったため、サーバー同居のローカル DB(MariaDB)へ集約しました。RDS で得られていた自動バックアップ/PITR は、日次バックアップ + 復元テストを自前で組んで代替しています。冗長性が本当に必要なワークロードでは RDS 継続が正解になる点は変わりません。
Q本番への切り替えはどのくらいのリスクですか?
旧本番を無改変のまま残し、新環境を並行構築しています。サーバーの切り替え・切り戻しは Elastic IP の付け替えだけで、DNS 変更を伴わず即座にロールバックできます。配信先(Bunny/CloudFront)の切替もサーバー設定 1 箇所で、アプリの改修・再デプロイは不要です。動画の正本は S3 にのみ保持し、CDN は使い捨てキャッシュとして扱うため、データ消失のリスクもありません。
