ブランチごとにDEV環境を動的生成!ALB で実現するプレビュー環境
はじめに
こんにちは。Frontend Rebirth(フロントエンドを再構築していく) チームの Maple です。
開発チームで「DEV環境が1つしかない」という状況、経験ありませんか?
私たちのチームでは、複数の機能を並行開発する中で、単一のDEV環境を共有していたことによる様々な問題に直面していました。
直面していた課題
1. コンフリクト
複数の開発者が同じDEV環境に変更をデプロイすると、お互いの作業が干渉し合い、コンフリクトが発生していました。
2. デプロイ待ち行列の発生
共通ブランチのCIが落ちていると、後続の確認は落ちているコードが修正されるまで待たなければならず、結果としてデプロイ待ち行列が発生していました。
3. レビュープロセスの困難
コードレビューで「実際の動作を確認したい」と思っても、DEV環境が別のブランチで占有されていると確認できない場合がありました。
設計
これらの課題を解決するため、ブランチごとに独立したDEV環境を動的に構築する仕組みを設計しました。

システムの流れの概要は以下の通りです。
- PRにラベル付与 → GitHub Actionsがトリガー
- Target Group作成 → ブランチ専用のターゲットグループ
- ALB Listener Rule追加 → HTTPヘッダーでルーティング
- ECSサービス起動 → ブランチ専用のコンテナ環境
- PRにコメント → アクセス方法を自動通知
なぜALB Listener Rulesなのか?
当初、以下の選択肢を検討しました。
- ALBのListener Rules: アプリケーション側での実装考慮は必要だが、低コストで実装可能
- Route53 + サブドメイン: DNS伝播時間、証明書管理の複雑化
最終的に、ALBのListener Rulesによるヘッダーベースルーティングを選択しました。
- 既存のALBを活用できるためコスト効率が良い
- 実装コストが比較的少ない
実装の詳細
1. GitHub Actionsによる環境構築
PRにdeploy-admin-devまたはdeploy-user-devラベルを付与すると、GitHub Actionsが自動的にトリガーされ、設計の処理を順次実行します。
2. 自動クリーンアップ
今回のような動的に環境を作成する仕組みを導入する際、最も重要なのがクリーンアップだと私は考えています。
単純にECSタスクのコストの増加が最も大きな課題です。
今回はコストの増加防ぐため、2つの異なるクリーンアップ機構を実装しました。
1: PRクローズ時の即時削除
PRがマージまたはクローズされた瞬間に、そのブランチに紐づくすべてのリソースを自動削除します。
2: 定期的なStaleリソース削除
毎日深夜3時に実行され、24時間以上使われていないリソースを自動削除します。
誤削除を防ぐため、以下の条件を満たすリソースのみを削除としています。
- ALB Listener Rule, Target Groupの場合、
Type=branchタグが付いている - ECSサービスの場合、
Branchタグから元のブランチ名を取得できる
導入効果
- 実装して間もないので、多くの方から声はいただいていませんが、使っていただいた方からは良いフィードバックをいただいております。
課題と今後
1. コスト監視
ブランチが増えるとECSサービスも増加し、コストが上昇するので直近数ヶ月は監視予定です。
今のライフサイクルだとコストが甚大すぎる場合は、クリーンアップの強化やモニタリングの強化が必要だと考えています。
2. Lambdaへの移行
共通のLambda関数を複数のリポジトリから呼び出す仕組みや、コードの再利用性を鑑みてLambdaへの移行を考えています。
3. 全ての環境への適応
現状Webのシンフロントエンド環境のみしか使用できないので、その他の環境全てで動作できるようにする予定です。
まとめ
単一のDEV環境共有による課題を、ALB Listener Rules + ECS + GitHub Actionsの組み合わせで解決しました。
この仕組みを先行的に新環境に導入することにより、組織全体でチーム全体の開発効率が向上し、並行開発がスムーズになるきっかけになったかと思います。
同様の課題を抱えているチームの参考になれば幸いです。
株式会社SODAの開発組織がお届けするZenn Publicationです。 是非Entrance Bookもご覧ください! → recruit.soda-inc.jp/engineer
Discussion