Amazon Web Services ブログ
閉域網でのマルチテナントアプリケーションテンプレート
最近では、地方公共団体や医療等の高いセキュリティレベルが求められる業界にクラウドが普及してきたこともあり、閉域でのマルチテナント設計のニーズも増えてきています。例えば、自治体の基幹システムの実装では総務省が示す「地方公共団体における情報セキュリティポリシーに関するガイドライン」及びデジタル庁が示す「地方公共団体情報システム非機能要件の標準」に準拠したセキュリティ対策を施す必要があります。
また、政府共通のクラウドサービスの利用環境である ガバメントクラウド では、複数の地方公共団体の環境を1つのベンダで管理する、共同利用方式が推奨されています。さらに、共同利用方式において、団体 (テナント) 間の環境分離方式についてはアカウント分離、ネットワーク分離、アプリケーション分離等による分離手法の検証が行われています。その中でもアプリケーション分離はコスト効率が良いテナント間の分離手法と言われています。
一方、閉域網でのアプリケーション分離による、いわゆる SaaS の実装例やサンプル情報はまだ少ないのが実情です。
そのため、今回パブリックセクターのソリューションアーキテクトが、 閉域網でのマルチテナントアプリケーションのサンプルテンプレートを公開しました。本テンプレートは前述の AWS Well-Architected フレームワーク SaaS レンズ で定義されている、 ブリッジモデル を採用しています。
技術要素としては、 AWS PrivateLink や Nuxt、 Keycloak を採用しているため、閉域での SaaS の実装を検討している方をはじめ、ガバメントクラウドにおいてアプリケーション分離を検討されている方、Keycloak on AWSに関心がある方にご参考いただけます。
ソリューション概要
テナント分離の詳細は SaaS ビジネスの成否を分けるテナント分離戦略 に記載がありますが、大きく分けると以下の3パターンです。
本テンプレートではブリッジモデルを採用した以下のアーキテクチャとなっており、Multi-tenancy環境とConsumer環境を各々のAmazon VPCにデプロイすることが可能です。
Consumer VPCとMulti-tenancy VPC間の通信は、Amazon Route53とAWS PrivateLinkを利用して閉域接続しており、WebアプリケーションはNuxtで実装しています。認証に関しては、Keycloakを利用して各Consumer VPCにあるActive directoryに対してLDAP認証させ、後述するサブドメイン情報で各Consumerのページにルーティングしています。
通信の整理
本テンプレートでは、下図のように VPC 間で 3 つの経路による通信が必要となります。
①端末からアプリケーションサーバへの通信、②端末から認証認可サーバへの通信、③認証認可サーバから Active Directory への通信 です。
団体間の環境をアカウント分離方式・ネットワーク分離方式で分離する場合、団体ごとに CIDR を設計できるため、各団体のネットワーク環境の CIDR と重複できないような設計ができ、 AWS Transit Gateway によるシステム間通信を行うことができます。
一方、アプリケーション分離方式を採用する場合、同じ VPC に複数の団体からアクセスされるため、CIDR 重複が起こり、Transit Gateway では正しく通信が行えなくなります。
そのため、今回は各団体の環境 (Consumer VPC) とアプリケーション環境 (Multi-tenancy Environment VPC) で双方向に Private Link を利用することで、CIDR 重複が起きていてもシステム間連携を行えるような実装にしています。
PrivateLink の詳細については AWS PrivateLink の概要 をご参照ください。
アプリケーションの設計
本構成におけるロードバランサー・アプリケーションコンテナのテナント分離について説明します。
本構成では、Elastic Load Balancer(ELB) に Network Load Balancerを採用しています。Application Load Balancer(ALB) はPrivateLink のターゲットに対応しておらず、機能的にも NLB で充足するためです。
一般的なブリッジモデルでは、NLB は団体間で共用するケースが多く見られます。自治体の要件として他自治体のアプリケーション画面が見えてはならないケースが想定されるため、本構成ではNLBを共用する構成(Shared NLB)の他、NLB を団体ごとに分離し、Endpoint によって制限をかけ、他自治体のアプリケーション画面に到達できないような構成 (Dedicated NLB)も選択できるようになっています。
テナントごとにアプリケーション画面を出し分ける方法として、テナントごとにパスを分ける (https://domain/a-corp/
) 設計や、ホスト名を分ける (https://a-corp.domain/
) 設計が考えられますが、今回は他自治体の他自治体のアプリケーション画面に到達できないようにするため、テナントごとにサブドメイン・ NLB を分け、コンテンツもサブドメインを元に出し分けています。具体的には、アプリケーションコンテナでは、アクセス元のサブドメインを元に、表示するコンテンツ・認証認可サーバの URL を使い分けています。一方で、アプリケーションコンテナに関しては複数のテナントで共用しており、コスト効率がよい設計となっています。
DB設計
本構成におけるデータベースのテナント分離について説明します。
本テンプレートでは自治体の基幹システムで採用されることが多いため、データベースエンジンとして PostgreSQL を、AWS のサービスとしてAmazon Aurora Serverlessを選定しています。
団体間の分離方式として、テナントごとにそれぞれ RDS インスタンスを用意し、それぞれのインスタンス内にテナント固有のデータベースを作成するサイロモデルを採用しています。理由としては、団体ごとに利用する暗号鍵を分けられるため暗号鍵消去が容易なことや、自治体によっては他団体とデータベースのインスタンスを分けるようなセキュリティポリシーを定めている場合があることから、サイロモデルを選定しました。
他にも様々なデータベースの分離方式があり、SaaS におけるデータパーティショニング設計の勘所 で詳しく解説を行っています。
上記で挙げた観点以外でも、個別の専用環境を用意するコストはどれくらいか、団体間でリソース共有 (インスタンス共有) する場合はノイジーネイバーにどういう対策を行うかなど、多方面から検討を行う必要があります。
また、テンプレートの実装では RDS Proxy を採用していますが、アプリケーションが利用するコネクション数が多くない場合は RDS Proxy を利用せず、直接データベースへ接続する実装も考えられます(RDS Proxyを利用しない場合は、config.tsのenableProxyをfalseに設定)。
認証
本構成における認証認可サーバの実装について説明します。
本テンプレートでは、認証認可サーバに Keycloak を採用しています。自治体の基幹システムの認証認可サーバでは、一般的な認証認可サーバが兼ね備えている機能の他、いくつかの追加の要件を満たすことが重要となります。
まず、「地方公共団体における情報セキュリティポリシーに関するガイドライン」に則るため、閉域でのアクセスに対応できることが必要となります。加えて、自治体の基幹システムにおいては認証認可サーバはユーザ認証機能だけでなく、システム間連携で利用される API の認証認可でも利用される可能性があります。その際「地方公共団体情報システム共通機能標準仕様書」に記載のある要件を満たす認証認可サーバを用意する必要がありますが、その要件も Keycloak で満たすことができるため、本テンプレートでは Keycloak を採用しました。
また、シングルサインオン (SSO) の実現には Open ID Connect (OIDC) を使用しています。OIDC は、安全かつ効率的な認証方法を提供し、ユーザー体験を向上させます。これにより、ユーザーは一度のログインで複数のサービスやアプリケーションにアクセスでき、作業効率が向上します。
既存 ID 管理システムの連携としては、自治体では既に ID 管理システムとして Active Directory を用いていることが多いため、LDAP を介して Active Directory と連携する実装としています。この連携により、既存の ID 管理システムをそのまま利用し、新しい認証システムへの移行をスムーズに行うことができます。
Keycloak は複数のテナントで共用し、realm をテナントごとに分離する構成としています。
Webアプリケーション
WebアプリケーションはNuxt(v3.8.2)で実装し、コンテナ実行環境であるAWS Fargateで稼働させ、Amazon ECSでコンテナ環境を管理しています。アプリケーションのAPIはserver/apiで定義し、useFetch
でDatabaseへのデータ取得/登録を行なっています。今回は単純処理のためAPIのロジックをNuxtのserver/api側で全て実装しましたが、AWS Lambda Function URLsや別のコンテナ環境で実装したWeb APIのエンドポイントをuseFetch
で利用することも可能です。Nuxtのデータフェッチに関してはこちらを参照ください。また、ルーティングに関しては、まずサブドメインを元に適切なKeycloakのrealmにルーティングし、router optionsを利用しており各Pageへのルーティングを実現させています。
まとめ
本ブログでは、閉域網でのマルチテナントアプリケーションについて、テナント分離や実装内容について説明いたしました。本テンプレートはKeycloakでの認証方式を採用しているため、閉域網での実装に関心のある方だけではなく、Amazon ECS + AWS Fargateを利用したKeycloakのコンテナ実装に関心のある方にも参考になれば幸いです。
テンプレートのコードはaws-samplesに公開しております。
著者について
松本 侑也 (Yuya Matsumoto)は、Public Sector 自治体担当のソリューションアーキテクトです。最近ではガバメントクラウドへの基幹システムの移行や、生成系AIの活用支援を中心に活動しています。
小泉 秀徳(Hidenori Koizumi)は、パブリックセクターのプロトタイピングソリューションアーキテクトです。最近のプロジェクトでは、生成系AIを活用したWebアプリケーション開発を行なっており、Next.jsやWebAssemblyに関心があります。