みなさん、こんにちは!プロダクト開発部の吉川です。
現在、JMDCが保有している医療ビッグデータを活用して生活者や医療に新しい価値を提供するプロダクト開発チームのバックエンドを担当しております。
今回は、フロントエンドを ECS から CloudFront に移行した話をします。
背景
SSR(Server Side Rendering)を実現するため ECS Fargate を構築しました。しかし、プロダクトの要件が調整されていくうちに、シンプルな SPA(Single Page Application)で十分であることがわかりました。運用・コスト面も踏まえて、CloudFront に移行する方が良いという判断に至りました。
旧構成で困ったこと
リリース時にダウンタイムが発生する
フロントエンドをリリースする際に数十秒のダウンタイムが発生しました。ECS のデプロイ戦略上、新しいタスクのビルドが完了する前に古いタスクがドレイン(既存の接続を徐々に切り離すこと)されてしまい、結果として一時的なサービス停止を招いていました。そのため、利用頻度の少ない時間帯に合わせてリリースをする運用となっており、リリースの柔軟さに欠けていました。
リリースに時間がかかる
GitHub Actions でリリースをしていますが、Docker イメージのビルド自体に時間がかかることに加え、ECS タスクの CPU アーキテクチャに ARM を採用していたため QEMU を使ったクロスコンパイルが必要となり、通常のビルドよりもさらに時間がかかっていました。
新しい構成
旧構成では ALB を経由してフロントエンドの ECS Fargate にアクセスをしていましたが、CloudFront を前段におき、S3 でフロントエンド(静的アセット)をホスティングする一般的な構成に移行しました。OAC(Origin Access Control)を使って S3 への直接アクセスを制御しています。今回の移行で特に工夫したポイントをピックアップしてご紹介します。

オリジングループによるフェイルオーバーの制御
旧構成では Route53 でフェイルオーバーをしていましたが、新しい構成では CloudFront でフェイルオーバーを実現しました。そうすることで同じドメインでメンテナンス画面に切り替えることができます。CloudFront でフェイルオーバーを実現するには CloudFront ディストリビューションのオリジングループを定義します。
「オリジン」でプライマリにフロントエンドの S3 のオリジンを指定し、セカンダリにメンテナンスページの S3 のオリジンを指定します。フェイルオーバー基準を指定することで対象のエラーステータスが返ってきたらメンテナンスページを開くように制御できます。

Lambda@Edge によるルーティングの制御
オリジングループを定義した場合、ルートディレクトリ(/)以外のパス(例: /hoge)を表示している状態でメンテナンスページに切り替えると、レイアウト崩れが発生することがわかりました。
対策として、CloudFront のオリジンリクエストイベントに Lambda@Edge を設定し、ルーティングを制御することでレイアウト崩れをせずにメンテナンスページを開くことができました。Lambda@Edge でメンテナンスページの S3 オリジンのリクエストかどうかを判定でき、その場合はルートディレクトリにリダイレクトするように実装しています。
まとめ
CloudFront に移行したことで、ダウンタイムの発生とリリース時間の長さという2つの課題が解決されました。時間帯を気にせずリリースでき、リリース時間も1分程度に短縮されました。また、Fargate の固定費がなくなりコスト削減にもつながりました。一方で手動でメンテナンスに切り替える運用になっているなどの課題が残っているので、引き続き改善していきたいと考えています。
最後まで読んでいただきありがとうございました!
JMDCでは、ヘルスケア領域の課題解決に一緒に取り組んでいただける方を積極採用中です!フロントエンド / バックエンド / データベースエンジニア等、様々なポジションで募集をしています。詳細は下記の募集一覧からご確認ください。
まずはカジュアルにJMDCメンバーと話してみたい/経験が活かせそうなポジションの話を聞いてみたい等ございましたら、下記よりエントリーいただけますと幸いです。
★最新記事のお知らせはぜひ X(Twitter)、またはBlueskyをご覧ください!