Amazon Web Services ブログ

AWS における SaaS アプリケーションのテナントルーティング戦略

SaaS プロバイダーにとって重要な課題は、テナントを特定し適切なリソースにリクエストをルーティングするための、セキュアで拡張性の高いテナントルーティング機構を設計することです。
効果的なテナントルーティングにより、分離性、拡張性、そしてセキュリティが確保されます。
この記事では、AWS 上のマルチテナント SaaS 環境における HTTP リクエストのルーティング戦略について、考慮事項、ベストプラクティス、そして例を交えて説明します。

トランスポート層でのルーティング戦略については、SaaS 向け AWS PrivateLink を使用したトランスポート層テナントルーティングのアプローチをご覧ください。

SaaS におけるテナントルーティングの概要

テナントルーティングは、SaaS アーキテクチャモデルに依存します。
プールモデルでは、複数のテナント間でインフラストラクチャリソースを共有します。
この場合、すべてのテナントに対して単一のリソースが存在するため、ルーティングは必要ありません。
一方、サイロモデルでは、テナントごとにインフラストラクチャリソースが専用に構築されます。
この場合、受信リクエストをテナント固有のリソースにルーティングするための効率的なテナントルーティングが不可欠になります。

Tenant routing in Pool and Silo SaaS models

ブリッジモデルは、サイロモデルとプールモデルを組み合わせたものです。この混合モデルは、階層化戦略やアーキテクチャ内のマイクロサービスに基づいてテナント間で適用できます。その結果、複数のルーティングメカニズムを使用する可能性があります。

テナントルーティング戦略

テナントルーティング戦略には大きく分けて 2 つのカテゴリーがあります。

  • ドメイン駆動型ルーティングは、Domain Name System (DNS) を使ってルーティングを決定します。SaaS プロバイダは、各テナントにサブドメインやドメイン名のプレフィックスを割り当て、アプリケーションを提供できます。
  • データ駆動型ルーティングは、受信した HTTP リクエストに含まれる情報を使ってルーティングを決定します。SaaS プロバイダは、さまざまな HTTP ヘッダ、リクエストパラメータ、クッキーを利用してルーティングロジックを実装できます。

ドメイン駆動型ルーティング

ドメイン駆動型ルーティングでは、各テナントに一意のホスト名を割り当てます。一般的なアプローチは、テナントごとにサブドメインを使用することです (例: tenant1.example.com)。ドメイン駆動型ルーティングの主な利点は、シンプルさです。DNS インフラストラクチャを活用することで、ホスト名だけからテナントコンテキストとルーティングを効率的に取得できます。しかし、アプリケーションが時間とともに進化するにつれ、複雑なシナリオでは柔軟性とカスタマイズ性に欠けるかもしれません。

考慮事項とベストプラクティス

バニティドメイン – ブランディングの利点を提供するために、SaaS プロバイダーはテナントに対し、カスタマイズされたパーソナライズされたバニティサブドメインの選択を許可することが多くあります。テナントのオンボーディングを高速化するために、最初はランダムなユニークなバニティドメインを生成し、後から変更を許可することができます。

独自のドメイン (BYOD) の利用 – ブランディングを強化するため、SaaS プロバイダーはテナントに対して Apex ドメインを利用できるようにすることができます。ただし、複雑さが増すためあまり一般的ではありません。
サブドメインでは、SaaS プロバイダーがドメインの所有権と TLS 証明書を管理します。一方、Apex ドメインでは、テナント自身がドメインを管理する必要があります。
ブランディングの利点と、ドメイン委任、検証、TLS 証明書の取得にかかる追加プロセスとのトレードオフを検討してください。

たとえば、AWS Certificate Manager (ACM) などのサービスを利用して TLS 証明書の更新を自動化できます。
これには、最初にドメインの所有権を証明するためのメールまたは DNS 検証が伴います。この検証は通常、テナントのオンボーディング時に要求されます。
ただし、自動化が常に可能というわけではありません。
たとえば、企業のお客様は、ドメインと TLS 証明書を厳密に管理するために、手動のプロセスを要求するかもしれません。

テナントディレクトリ – ドメイン駆動型のルーティングでは、ユーザーがテナントの URL を覚えておく必要があります。しかし、一部のユーザーは URL を忘れてしまう可能性があるか、SaaS ソリューションに直接アクセスする場合はさらなるガイダンスが必要になる場合があります。そのため、ユーザーのメールアドレスやユーザー識別子に基づいてテナントを特定できるようなエクスペリエンスを設計することをご検討ください。そのようなエクスペリエンスの例を以下に示します。

Tenant Directory User Experiences

図 2: SaaS ソリューションの一環としてテナントに提供できるユーザー エクスペリエンスの例

Amazon Route 53 と Application Load Balancer を使用した例

ドメイン駆動のルーティングを実装するには、受信リクエストのルーティングに使用する AWS サービスに依存します。この例では Application Load Balancer を使用し、リスナールールを使って受信リクエストのホストヘッダーに基づいた条件式ロジックを設定します。
各テナントをプロビジョニングする際、ルーティングを設定してユーザーを適切なテナントリソースに振り分けます。

Example domain-driven routing architecture with Application Load Balancer (ALB) listener rules

図 3: Application Load Balancer のリスナールールを使ったドメイン駆動型ルーティングの例

Amazon Route 53 による DNS – HTTP リクエストでは DNS が最初の入り口となります。この例では、Amazon Route 53 にエイリアス DNS レコードを設定し、すべての *.example.com サブドメインに関連するトラフィックを Application Load Balancer にルーティングします。

アプリケーションロードバランサーを使用したホストベースのリスナールール – トラフィックがロードバランサーに流れる際には、HTTP ホストヘッダーが含まれています。例えば、tenant1.example.com などです。そして、そのリクエストをテナントに割り当てられたリソースに対応するターゲットに転送します。

テナントのオンボーディングテナントのオンボーディングの一部としてテナントルーティングを検討してください。
例えば、新しい SaaS 顧客が登録した際、その ティア に基づき、テナントのオンボーディングサービスで新しいインフラストラクチャがプロビジョニングされる必要があるかどうかを判断できます。
必要な場合は、インフラストラクチャのプロビジョニングに加えて、テナントルーティングを設定する必要があります。
この場合、新しいテナントインフラストラクチャに対応するホストベースのリスナールールを設定してください。

これはドメインベースのルーティング手法の一例にすぎないことに注意してください。Application Load Balancer を使用していますが、ここで説明されるコンセプトは他の技術に対しても適用できます。

データ駆動型ルーティング

次にデータ駆動のルーティングについて見ていきましょう。SaaS アプリケーションでは主要な設計原則として、ユーザー ID とテナント ID を関連付けることです。
これにより SaaS ID が生成され、システムの全レイヤーを通過して、テナントコンテキストにアクセスできるようになります。
データ駆動のルーティングでは、この ID を HTTP リクエストの部品に含めることができます。
これにはヘッダー、Cookie、URL パス (URI) 、リクエストボディなどがあります。
次に、この情報を抽出して、着信リクエストを適切なテナントのリソースに動的にルーティングします。

データ駆動型ルーティングの重要な利点は柔軟性です。ただし、ルーティングのための追加算出が必要なため、手法には複雑さと運用オーバーヘッドが加わります。そのため、特に大規模な SaaS 環境では、細心の設計が求められます。

考慮事項とベストプラクティス

テナント ID 管理 – データ駆動型ルーティングでは、一般的なアプローチは、API キーや OAuth クライアント ID のようなテナントコンテキストをユーザー認証時に取得することです。ただし、このアプローチは SaaS アプリケーションに集中型 ID サービスがあることを前提としています。場合によっては、SaaS アプリケーションには各テナントごとに別々の ID サービスがある可能性があります。そのような状況では、適切な ID サービスを決定するために認証前にテナントコンテキストが必要になります。そのため、ドメイン駆動型ルーティングの方がより適切なアプローチかもしれません。

ワイルドカードサブドメイン – SaaS ソリューションでは自動化が重要であり、一般的なアプローチは各テナントにサブドメインを提供することです。ワイルドカードサブドメインでは、DNS を 1 回設定するだけで、新しいテナントをオンボードする度に追加の DNS 操作は必要ありません。たとえば、Amazon CloudFront にワイルドカードの代替ドメイン *.example.com を設定します。サービスは、そのパターンに一致するトラフィックを、アプリケーションが存在するオリジンにルーティングします。そして、アプリケーションでテナントのコンテキストを抽出し、リクエストを適切なテナントにルーティングできます。ワイルドカードサブドメインは、Amazon API GatewayApplication Load BalancerAWS Amplify などのサービスでサポートされています。

キャッシュを利用したコスト最適化とパフォーマンス最適化 – ルーティングロジックの実行には、コストとパフォーマンスのオーバーヘッドが発生します。そのため、実行頻度を最小限に抑えることを検討してください。例えば、初期認証プロセス中にのみルーティングロジックを実行します。同じユーザーやテナントからの後続のリクエストではキャッシュされたルーティング結果を利用することができます。

高度なコンテキスト – 一部のユースケースでは、テナントの識別子以外の追加のテナントコンテキストが必要になる場合があります。これには、バックエンドリソースへの参照、アプリケーションバージョン、またはCloudFront ヘッダーから抽出されたジオロケーションデータなどが含まれ、マルチリージョンアーキテクチャーで特に役立ちます。このような状況では、Amazon CloudFront KeyValueStoreAmazon DynamoDB などの低レイテンシーのキーバリューストアにこの詳細なテナント情報を保存することを検討してください。これにより、ルーティングにこれらの詳細を効率的に取得できます。

Amazon Route 53 と CloudFront による事例シナリオ

ドメイン駆動のルーティングと同様に、データ駆動ルーティングの実装は、着信リクエストを処理するために選択するテナントルーティングサービスに依存します。
この例では、CloudFront をアプリケーションへの最初のエントリポイントとして使用します。
テナントコンテキスト (例: tenant-id) を取得し、条件付きでリクエストを転送する発信元 (サービス) を選択することで、Lambda @ Edge でルーティングロジックを構成します。

Data driven routing with Amazon CloudFront

図 4: CloudFront の Lambda @ Edge を使用したデータ駆動型ルーティングの例

Amazon Cognito を使ったユーザー認証 – テナントのコンテキストを取得するには、まず Amazon Cognito などのアイデンティティプロバイダを使ってユーザーを認証します。
認証すると、アイデンティティプロバイダから JSON Web トークン (JWT) が発行されます。
このトークンには、ユーザーが所属するテナントが含まれています。
次に、このトークンを認証 HTTP ヘッダに含めて、その後の HTTP リクエストを送信します。

Amazon Route 53 による DNS – データ駆動型ルーティングでは、たとえば www.example.com のように単一のドメインを使用して、すべてのテナントにアプリケーションへのアクセスを許可し、HTTP ヘッダにテナントのコンテキストを埋め込む場合があります。この例では、Amazon Route 53 に別名 DNS レコードを設定して、www.example.com に関連するすべてのトラフィックを CloudFront ディストリビューションにルーティングします。

CloudFront の Lambda @ Edge での認証ベースのルーティング – CloudFront ディストリビューションにトラフィックがルーティングされると、それには以前にアイデンティティプロバイダから取得された暗号化 JWT を含む HTTP 認証ヘッダーが含まれています。この JWT には、ユーザーのテナントコンテキスト、たとえば tenant-id:tenant1 が含まれています。次に、Lambda @ Edge を設定して JWT を復号化し、テナントコンテキストを抽出します。JWT を検証するには、アイデンティティプロバイダから公開鍵を取得します。検証された後、リクエストをそのテナントに属するオリジンに転送します。このプロセスの詳細については、authorization with Lambda @ Edge and JWT をご覧ください。

テナントのオンボーディングテナントのオンボーディングの一部としてテナントルーティングを検討してください。
たとえば、新しいテナントのインフラストラクチャをプロビジョニングする際、Lambda @ Edge のルーティングロジックを更新して新しいテナントを考慮できます。
より拡張性の高いアプローチとしては、低レイテンシーのキーバリューストアにテナントから Origins へのマッピングを維持し、Lambda @ Edge のロジックからこれを参照することで、ルーティング決定をすることができます。
新しいテナントがオンボーディングされた際は、新しいルートを考慮するために新しいエントリを追加できます。

テナントルーティングの実装

テナントルーティングの実装方法は、SaaS アーキテクチャ、特に SaaS アプリケーションのエントリーポイントを処理するサービスに依存します。
サービスを選択する際は、ルーティング機能に加えて、パフォーマンス、セキュリティ、コストなどの一般的な要件を考慮する必要があります。

例えば、CloudFront と Lambda @ Edge を使って、データ駆動型のルーティングを行うだけでなく、レイテンシを削減し、DDoS 攻撃からセキュアにすることもできます

別の例は HTTP リバースプロキシの利用です。その軽量な性質によりデータ駆動型のルーティングを効率的に実行できます。Kubernetes アーキテクチャでは、認証済みリクエストやテナントへのルーティングを管理するために、サービスメッシュを追加で利用することが一般的です。詳細はSaaS Identity and Routing with Amazon EKSを参照してください。

別の実装アプローチは、API Gateway を使用することです。API Gateway は、ワイルドカードカスタムドメインLambda オーソライザーを提供しており、ドメイン駆動型とデータ駆動型のルーティングアプローチをサポートします。
さらに、API Gateway は SaaS アプリケーションでも人気があり、スロットリングによる各テナントのリクエストをコントロールできるため、ノイジーネイバーの影響を最小限に抑え、パフォーマンスを最適化できます。

スケーラビリティとシャーディングに関する考慮事項

テナントルーティングのアプローチに関係なく、拡張性は重大な検討事項です。テナントを増やしてオンボードしていくためです。

サービスクォータによってルーティングロジックにおける最大ルート数に制限が設けられる可能性があることに注意してください。たとえば、Application Load Balancer のシナリオでは、テナントごとにリスナールールに依存します。CloudFront のシナリオでは、配布およびリクエストごとの関数に制限のある Lambda @ Edge に依存します。さらに CloudFront には、配布ごとのドメイン名と SSL 証明書に制限があります。これらの制約は、様々なアーキテクチャの決定につながります。

これらのスケール制限を克服する高度なアプローチの 1 つは、セルベースのアーキテクチャを採用することです。これはテナントを シャードの分割単位に分けます。
ここでは、受信リクエストをまずシャードに、その後、シャード内のテナントにルーティングします。

Tenant routing for SaaS in a cell-based architecture

図 5: プールされたテナントのリソースシャーディングを伴う SaaS アプリケーションでのテナントルーティング

まとめ

テナントルーティングは SaaS アプリケーションを構築する際に慎重に検討する必要があります。この記事では、ドメイン駆動のルーティングとデータ駆動のルーティングという 2 つの戦略を検討しました。簡単なテナントごとのサブドメインから、HTTP リクエストの内容に基づく高度なダイナミックルーティングまで、さまざまなアプローチについても説明しました。テナントルーティング戦略を設計する際は、スケーラビリティ、オペレーション、コストのトレードオフを検討する必要があります。さらに重要なのは、SaaS モデルに合致し、お客様にご期待の体験を提供できることです。さまざまなアプローチを評価し、目標ビジネスに合わせることで、お客様のニーズの変化に対応できる、安全でスケーラブルな SaaS アプリケーションを構築できるはずです。

SaaS アプリケーションの構築方法の詳細は、AWS Well-Architected SaaS Lens をご覧ください。

本稿は、2024年6月25日に Networking & Content Delivery で公開された “Tenant routing strategies for SaaS applications on AWS” を翻訳したものです。翻訳は Solutions Architect の長屋が担当しました。