CloudFrontのディストリビューションを分割して、マルチステージング環境をさらに便利にした話

こんにちは、普段PRTIMES STORY(以下STORY)の開発リーダーをしている岩下(@SardineTa23)です。

以前ECSのマルチステージング環境を設計・実装した記事を書きました。

あわせて読みたい
ECSでマルチステージング環境を実現した設計と実装
ECSでマルチステージング環境を実現した設計と実装こんにちは、普段PR TIMES STORY(以下STORY)の開発リーダーをしている岩下(@SardineTa23)です。PR TIMES STORYは弊社のMissionである「行動者発の情報が、人の心を揺...

こちらのマルチステージング環境をSTORYに導入したおかげで、開発フローのボトルネックが解消され、大きいプロジェクトが進行している期間にも小さな変更をステージング環境でQA→リリースできるようになりました。

ところが、こちらのプロジェクトを進行中に、実装したマルチステージング環境では太刀打ちできない問題が見つかりました。CloudFrontの設定によって、PR TIMESに導入されていたマルチステージングとの噛み合わせが悪くなっていたのです。

本記事ではステージング環境のCloudFrontディストリビューションを分割して、複数のアプリケーションのマルチステージング環境を連携させた背景と方法について述べていきたいと思います。

目次

前提

発生した問題について述べる前に、PR TIMESとSTORYのマルチステージング環境について簡単に説明します。

STORYのマルチステージング(ECS)

以前紹介したマルチステージングのざっくりとした概要は以下です。

  1. 通常ステージング環境ドメインはstory-dev.example.comである。
  2. 開発者は個人のステージング環境hoge.story-dev.example.comというサブドメインを作成して使用する。
  3. 前もってhoge.story-dev.example.comのためのALBのリスナールールやターゲットグループを作成しておく。
  4. GitHub Actionsを使用して、任意のタイミングでhoge.story-dev.example.comに対応するECSサービス・タスクを作成する。

上記の設定をすると、ALBに直接来たリクエストを、ALBのホストベースのルーティングを使ってそれぞれのECSへとルーティングするといったものでした。

PR TIMESで既に動作してたマルチステージング(EC2)

PRTIMES STORYとは別に、PR TIMESのステージング環境ではApacheのVirtualDocumentRoot

を使用したマルチステージング環境が運用されていました。

あわせて読みたい
1台のサーバーで複数のステージング環境を同時に使えるようにする
1台のサーバーで複数のステージング環境を同時に使えるようにするこんにちは、インフラチームテックリードの櫻井です。今回は1台のサーバーで複数のステージング環境を同時に使用できるように設定を変更したので、その方法について紹介...

PR TIMESのマルチステージングの概要は以下です。

  • example.comという通常のステージングドメインと環境が存在する。
  • hoge.example.comという環境でhogeさんがデプロイしたアプリケーションを実行できる。
  • リクエストは通常のステージングと同じ経路(CloudFront→ALB)をたどって、通常のステージングと同じEC2へ到達する。
  • リクエストのドメインに応じて、ドメインと同じ名前のディレクトリにあるアプリケーションコードが実行される。

既存マルチステージング環境の問題が発覚したプロジェクト概要

ざっくり説明すると、PR TIMESのサーバーで動作しているアプリケーションの一部となっていたSTORYのコードを、STORYサーバーのアプリケーションに移植させるといったものです。

あわせて読みたい
PR TIMES STORYを別リポジトリに移植した話
PR TIMES STORYを別リポジトリに移植した話こんにちは、普段PR TIMES STORY(以下STORY)の開発リーダーをしている岩下(@SardineTa23)です。今回はリリース当時からSTORYが抱えていた課題とそれを解消した方法に...

移植前

ドメインprtimes.jpprtimes.jp/storyadmin-story.prtime.jp
対応サーバーPR TIMESサーバーPR TIMESサーバーSTORYサーバー

移植後

ドメインprtimes.jpprtimes.jp/storyadmin-story.prtime.jp
対応サーバーPR TIMESサーバーSTORYサーバーSTORYサーバー

発生した問題

以下はPR TIMESとSTORYのステージング環境で使用しているドメインとサーバーの対応表です。

123456
ドメイン(+ パス)example.comexample.com/storyhoge.example.comhoge.example.com/storystory-dev.example.comhoge.story-dev.example.com
環境PR TIMES
通常ステージング
PR TIMES
通常ステージング
PR TIMES
マルチステージング
PR TIMES
マルチステージング
STORY
通常ステージング
PR TIMES
マルチステージング
対応サーバーPR TIMES
サーバー(ALB/EC2)
PR TIMES
サーバー(ALB/EC2)
PR TIMES
サーバー(ALB/EC2)
PR TIMES
サーバー(ALB/EC2)
STORY
通常ステージングALB/ECS
STORY
マルチステージングALB/ECS
対応表を図にしたもの

移植のプロジェクトの目標は、PR TIMESのドメイン(本番ならprtime.jp、ステージングならexample.com)の/storyというパスへのリクエストをSTORYのALB・ECSで処理することです。対応表でいうとのリクエストをSTORYのALBに向けたいです。

それをステージング環境で検証するためにCloudFrontのパスベースのルーティングを使用して、/story のOriginをSTORYのALBにしようとしました。ここで問題に遭遇します。

CloudFrontにはホストベースのルーティング機能が存在しません。

そのため、同じディストリビューション内で通常ステージングとマルチステージングのリクエストを捌いていると、/storyのパスにリクエストが来た際、通常ステージングかマルチステージングのどちらかしかOriginとして選択できないということに気が付きました。

期待する挙動

せっかく個人が自由なサブドメインをPR TIMES、STORY両方で発行して各々のステージング環境にデプロイできる環境があるので、PR TIMESとSTORYのマルチステージングを連携したいなという気持ちになりました。

具体的には、hogeというサブドメインでSTORYのマルチステージングをデプロイをしたら、PR TIMESと連携する際はhoge.example.comというステージング環境と連携するなどのようにして、同じサブドメインの2つのアプリケーションをつなぎ合わせるイメージです。

理由としては、PR TIMESとSTORYに同時に変更を入れる必要があるプロジェクト(今回の様なプロジェクト)が始まった時にマルチステージング同士が通信できれば、通常ステージングにデプロイする必要がなくなり個人のサブドメイン環境で完結できるためです。

変更点

上記の期待する挙動を叶えるために、マルチステージングのアプリケーション側、インフラ側にそれぞれ少し変更を加えました。

アプリ側

STORYは環境変数でPR TIMESのAPIを叩くために使用するPR TIMESドメインを保持しています。こちらはステージング環境であれば.env.stagingファイルにハードコーディングされているexample.comというドメインです。この環境変数をアプリケーションデプロイ時にhoge.example.comなどに書き換える事ができれば、任意の環境のPR TIMESマルチステージングにAPIリクエストを飛ばせるようになります。

sed -i -e "s/PRTIMES_URL=https:\\/\\/example.com/PRTIMES_URL=https:\\/\\/${SUBDOMAIN}.example.com/g" .env.staging

こんな感じの力技で、PRTIMES_URL という環境変数をGitHub Actionsの中で書き換えました。

こちら変更が反映されたアプリケーションコードをImageに固めてECSにデプロイすることで、ECSが連携するPR TIMESのステージング環境のドメインを変更しました。

インフラ側

CloudFrontがホストベースのルーティングができないため、どうにかならないかな〜と思っていたのですが、そもそも同じディストリビューションでリクエストを捌く必要がないのでは?と気づきました。

通常ステージングのドメインとマルチステージング用のワイルドカードのサブドメインを別々のディストリビューションに分割してしまえば、ホストごとのルーティングを考える必要がなくなります。

また、Lambda@Edgeを使うと別々のホストに対して別々のOriginを指定できるようなのですが、料金的にもメリットがないし管理が複雑になると思ったので見送りました。

やったことは以下です。

  • マルチステージング用に新規のCloudFrontディストリビューションを作成
  • 通常のディストリビューションとマルチステージングのディストリビューションをそれぞれ指すRoute53のレコード作成
  • 通常ステージングのディストリビューションの/storyのオリジンを通常ステージングのALBとする
  • マルチステージングのディストリビューションの/storyのオリジンをマルチステージングのALBとする

こうすることで、hoge.example.com/storyのようなリクエストはSTORYのマルチステージングALBへと流れていき、ALBのホストベースのルーティングを使用してhoge用のECSへと到達するようになります。

新規のディストリビューションを作成する時に設定がIaC化されていたおかげで、ほぼコピペコードをterraform applyするだけで作成できました(ホント便利)。

まとめ

別々のアプリケーションのマルチステージングを、上記のような方法で連携することで、移植のプロジェクトもサクサクとQA→リリースの流れを作ることができました。

上記の仕組みは先日リリースされたPR TIMES Webクリッピングβ版でも導入されており、弊社のECS環境での開発速度を向上しつつあります。

AWSを使った開発環境の構築・改善に興味がある方はぜひ下記のフォームからカジュアル面談などを申し込んでいただけると幸いです。

株式会社PR TIMES
カジュアル面談申し込みフォーム - 株式会社PR TIMES
カジュアル面談申し込みフォーム - 株式会社PR TIMES株式会社PR TIMESでは現在00-0. カジュアル面談(全職種OK)を募集しています。

この記事を書いた人

PR TIMES STORYの開発をしています。
AWSのSAA/DVA/SOA/SAPを持ってます。

目次
閉じる