見出し画像

ガバメントクラウドで考える静的Webサイト向けアーキテクチャ

デジタル庁クラウドチーム
Cloud Engineer 加藤諒

前回のnote記事「Web APIアーキテクチャ」を説明した回では、バックエンドアプリケーションの典型的なアーキテクチャパターンとして、REST等のWeb APIを使ったアーキテクチャをガバメントクラウドでどう考えているかについて説明しました。

今回は、別の典型的なアーキテクチャパターンとして、Web APIと合わせて利用されることもある、静的Webサイト向けのアーキテクチャについて説明します。なお、現在ガバメントクラウドではAWSとGCPを利用することが可能ですが、今回はAWSを使った例を示し、主要なAWS利用料の参考試算も含めてご紹介します。

想定するシチュエーション

個人を識別せず、サインインする仕組みのない、完全にパブリックなWebサイトを構築するシチュエーションを想定します。「Web APIアーキテクチャ」で紹介したようなアプリケーションをバックエンドで併用するケースも増えてきていますが、そのバックエンドの費用や詳細な構成は含めません。

将来的に厳しい非機能要件や柔軟な拡張性が求められることを念頭に、Webサイトの総容量は200MBで、1日に10,000リクエストがあると想定してアーキテクチャを検討します。

静的Webサイトとは

本文における静的Webサイトとは、クライアントからのリクエストに対してサーバーサイドから静的なHTML、CSS、JavaScript、画像など主にブラウザでの表示に使う静的ファイル群を返す仕組みを意味します。

従来は、静的Webサイトを構築しようとすると、Webサーバを立てて、パソコンや別の場所で作ったHTMLファイルや画像等の静的ファイルをリモートコピーしてきて配置してコンテンツ配信していました。

最近は、Nuxt.jsやNext.jsといったフレームワークを使って、コンテンツが更新されたタイミングでWebサーバ上で静的ファイルを更新して新しいコンテンツを反映させておき、ユーザからのリクエストが来たらそのあらかじめ更新しておいた静的ファイルを返すという手法を取ることが多くなってきました。

従来のWebアプリケーションで使われてきたWebサーバ上で画面を動的に生成してクライアントに返すSSR (Sever Side Rendering)に対して、SG (Static Generation)と呼ばれる手法となります。

また、SGとCSR (Client Side Rendering)を組み合わせて、SGでページを配信し、そのページの一部をCSRで動的に更新しつつページ遷移していくようなMPA(Multi Page Application)による静的Webサイトも多く見られるようになってきています。

採用する技術スタック

本文では前述のシチュエーションに基づき、Next.jsを使いSG・CSRする構成を採用した例にします。

言語はTypeScript、コードのリポジトリにはGitHubを使用します。クラウド環境については、今回はガバメントクラウドとして採用されているAWSを使った例とし、CI/CDにAWSのCodeシリーズ、デプロイにはCDKを使う例となります。

デプロイにはAWS CDKを使用します。

アーキテクチャ

画像

想定するシチュエーションと技術スタックより、上図のようなアーキテクチャが採用可能です。図は本番環境のみを表現していますが、検証環境との2環境を作成している想定です。

SSRを行わないため、Amazon EC2やAWS App Runnerのようなコンピュートサービスの利用は不要で、静的ファイルを配信できる、Amazon CloudFront + Amazon S3や、AWS Amplify Consoleを利用できます。

今回は将来的に非機能要件が追加される可能性が高いことを考慮して、細かい対応が出来る余地のあるCloudFront + S3構成を採用しました。SGを行うNext.jsはCodeBuildで実行されます。Github ActionsからCodePipeline経由で呼び出し、コンテンツを取得して静的ファイルを生成しS3にアップロードします。S3からフロントエンドのデプロイはCDKのS3 Deploymentで実行して行います。

CDK S3 Deploymentは、内部でAWS Lambda Functionを使用するCloudFormation Custom Resourceを使用しており、これ単体でS3バケットへの展開とCloudFrontのInvalidation(キャッシュの無効化)を行ってくれます。

GitHub ActionsからAWSへデプロイの認可はOpen ID Connectを利用してIAMロールの取得をしています。これによりアクセスキーのハードコードを回避できアクセスキーのローテーションなどの運用から解放されます。

URLパスの末尾に自動で/index.htmlを追加するために、CloudFront Functionsを利用しました。CloudFront Functionsは、検証環境のアクセスを制限するためのBasic認証にも利用しています。

GithubからAWSへのデプロイのCI/CDの流れはAWSのCodeシリーズで実現していますが、その構成はCDK PipelineというCDKのコンポーネントを使用しています。Codeシリーズを高度に抽象化しCI/CDのパイプラインの導入を簡単にしてくれます。

GitHubではブランチ戦略にGitLabフローを採用し、検証(Staging)環境はstgブランチという名前のブランチに、本番(Production)環境はprdブランチという名前のブランチに紐付けます。

想定されるクラウド環境のコスト

画像

今回はAWSの環境を想定して主要な機能の概算を、2022/02/25時点の公になっている価格リストから、想定システム利用に合わせて計算しました。

検証・本番の両環境のCI/CDパイプラインも含めて月額4.27USD(1USD115円換算で491.05円)の費用が発生します(ap-northeast-1 リージョンの場合)。この見積もりでは、無料利用枠については考慮から外しています。

今回の構成にはAWS Key Management Serviceによる暗号化やAmazon CloudWatch ダッシュボードによるモニタリングなどの費用は含んでいません。

ガバメントクラウドでの静的Webサイトの考え方

ガバメントクラウドは利用システムのインフラとなるクラウドを提供していきますので、アプリケーションアーキテクチャについては利用システム側で検討いただきます。

一方で、コスト効率、迅速性、柔軟性、セキュリティの実現を目指すガバメントクラウドとしては、静的Webサイトを実現するには、インフラの観点からここで説明してきたようなSGベースのアーキテクチャにコストメリットがあると考えられるでしょう。

Next.js等を使ったSGアーキテクチャとすることで、スケーラビリティの高いCloudFrontやS3を使ってコンテンツを配信でき、大規模なユーザ数やアクセス数の急増にも耐えうるスケーラブルな静的Webサイトを実現できます。

サーバインスタンスを大量に並べてスケーラビリティを実現するよりも、このアーキテクチャではコスト削減を実現しながらスケーラビリティも確保できることが利点と考えられます。

このような、迅速でスケーラビリティがあり可用性が高くコストパフォーマンスの良いアーキテクチャを実現しやすくするように、ガバメントクラウドとしてこのアーキテクチャをデプロイできるIaCテンプレートを用意することも検討していきます。

関連するデジタル庁の採用情報は以下のリンクをご覧ください


デジタル庁Techブログの記事一覧は以下のリンクをご覧ください

デジタル庁の採用に関する情報は以下のリンクをご覧ください


ピックアップされています

デジタル庁Techブログ

  • 33本
デジタル庁公式noteです。 デジタル庁の政策やサービス開発背景、働く職員などをご紹介します。 ウェブサイト: https://www.digital.go.jp/ 運用ポリシー: https://www.digital.go.jp/social-media-policy/
ガバメントクラウドで考える静的Webサイト向けアーキテクチャ|デジタル庁
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word

mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1