Amazon Web Services ブログ

AWS における Account-per-Tenant 型 SaaS 環境のライフサイクル管理

このブログは「Managing the account lifecycle in account-per-tenant SaaS environments on AWS」を翻訳したものです。

SaaS(Software as a Service)企業がアプリケーションにマルチテナントを導入する場合、多くの選択肢があります。AWS SaaS Factory プログラムでは、コスト、コンプライアンス、エンドカスタマーの要件などの要素に応じて、さまざまなデプロイメントパターンを推奨しています。

VPC-per-Tenant のようなサイロ方式では不十分な場合があります。例えば、規制の厳しい業界のアプリケーションや、事業ドメインや顧客の要件、レガシーアプリケーションを AWS に移行する場合などです。このような場合、テナントごとに AWS アカウントをプロビジョニングすることを検討してください。

このブログでは、Account-per-Tenant を採用した SaaS 環境の構築における AWS アカウント管理についてご紹介します。推奨されるアカウントのライフサイクルと、どのようにアカウントのベースラインを設定し、使用開始後のアカウントをどのように維持するかについての情報を提供します。この投稿は、最大で数千のテナントに SaaS プロダクトを提供している独立系ソフトウェアベンダー(ISV)を対象としています。もし SaaS アプリケーションが、より多くのテナントを抱える可能性がある場合は、このアカウントの構造を使わないでください。

前提知識

読み進める前に、ブログ「AWS Organizations における組織単位のベストプラクティス」と、ホワイトペーパー「Organizing Your AWS Environment Using Multiple Accounts」の概念をよく理解しておいてください。このブログで説明されている戦略は、ホワイトペーパーで説明されている戦略と共に実行する必要があります。ホワイトペーパー「SaaS Tenant Isolation Strategies」で推奨されている分離モデルについて、理解しておく必要があります。また、AWS Well-Architected フレームワークの SaaS レンズにおけるテナントの定義についても理解しておく必要があります。

AWS Organizations を使ったテナント環境の管理

AWS アカウントを使用してテナントを分離する場合、プールモデルや、VPC-per-Tenant のようなサイロモデルに属する他のタイプにはない固有の課題があります。各テナントがそれぞれアカウントを受け取る場合、管理する AWS アカウントが数千におよぶ可能性があります。これらをそれぞれ個別に管理するのは、扱いにくいことがあります。幸いにも AWS Organizations では、複数の AWS アカウントの自動作成と管理ができます。

図 1 は、典型的な Account-per-Tenant モデルを表しています。1 つの管理アカウントと、3 つの組織単位(OU)があります。Infrastructure OU には、ホワイトペーパー「Organizing Your AWS Environment Using Multiple Accounts」で定義されているように、オーケストレーションメカニズム、認証、中央化されたロギングなど、共有のサービスを持つアカウントが含まれています。Workload OU と Suspended OU には、テナントごとにプロビジョニングされたアカウントが含まれています。それぞれの AWS アカウントは、テナントごとに 1 対 1 でマッピングされます。Workload OU のアカウントには、テナント専用のプロダクションレベルのインフラストラクチャが含まれます。Suspended OU のアカウントは、使用されなくなったアカウントです。AWS リソースは含まれていません。

管理アカウントは、アカウントの作成や AWS Organizations の変更など、組織内の他のアカウントではできないアクションを実行できます。そのため、管理アカウントは OU の外に存在しており、他の AWS アカウントにサービスを提供するために使用してはいけません。管理アカウントの目的の詳細については、AWS Organizations の用語と概念をご参照ください。

図 1 は、この構成のデプロイ方法の例です。

3 つの OU は、インフラストラクチャ、ワークロード、サスペンドです。Infrastructure OU には共有サービスが含まれています。Workload OU には、テナントに割り当てられていないアカウント、またはテナントに割り当てられているアカウントが含まれています。Suspended OU には、テナントによってアクティブに使用されなくなったアカウントが含まれています。管理アカウントは特定のタスクにのみ使用されます。

図 1:Account-per-Tenant 分離の構成

タグ付けフロー

データプレーンは、Workload と Suspended という 2 つの独立した OU で構成されています。これらの OU の目的は、ホワイトペーパー「Organizing Your AWS Environment Using Multiple Accounts」で説明されています。OU 間でのアカウントの移動を最小限に抑えるには、タグを使う必要があります。タグには、アカウントのステータスと、テナントの割り当てという 2 つの目的があります。ACTIVE、SUSPENDING、または SUSPENDED をタグ付けしたアカウントは 1 つのテナントに利用し、決して別のテナントで再利用しないでください。

アカウントがプロビジョニングされると、BASELINING タグが割り当てられます。ベースライン化タスクが完了すると、BASELINED タグが割り当てられます。アカウントがテナントに割り当てられると、ACTIVE タグと TENANT_ID タグが割り当てられます。テナントがサービスを中止すると、リソースが削除される間、アカウントは Suspended OU に移動し、STATUS タグは SUSPENDING タグに変わります。リソースが削除されると、STATUS タグは SUSPENDED に変わります。

図 2:アカウントのライフサイクルにおける STATUS タグのフロー

BASELINING タグ

新しくプロビジョニングされ、まだ使う準備が整っていない AWS アカウントであることを示しています。このベースラインを設定するプロセスでは、コストはかからないがアカウントに必要な変更をします(メンバーアカウントのエンタープライズサポートを有効化、サービスクォータの緩和、IAM ロールの作成など)。ベースラインの設定が完了すると、このアカウントは BASELINED タグで再度タグ付けされます。

BASELINED タグ

テナントにまだ割り当てられていないアカウントであることを示しています。これらのアカウントは、すでにエンタープライズサポートが有効になっており、サービスクォータが設定されています。アカウントへのベースラインの設定はすぐには完了しないため、このタグを持つアカウントをプールしておく必要があります。このタグを持つアカウントの数は、新規テナントのオンボーディングの頻度に依存します。

ACTIVE タグ

現在、テナントに割り当てられているアカウントであることを示しています。1 つのテナントごとに、1 つのアカウントが割り当てられます。アカウントがテナントに割り当てられると、TENANT_ID タグの値には、UUID など一意のテナント ID が設定されます。

SUSPENDING タグ

テナントで使用されなくなり、削除する必要のあるリソースがまだ残っているアカウントに使われます。テナントがサービスを中止した後は、アカウント内のリソースをデプロビジョニングしなければなりません。まず、アカウントが Workload OU から Suspended OU に移動されます。STATUS タグの値が、ACTIVE から SUSPENDING に変更されます。そして SaaS アプリケーションの自動化により、AWS CloudFormation テンプレートなどのリソースがアカウントから削除されます。アカウントのリソースがデプロビジョニングされると、アカウントの STATUS タグの値は SUSPENDED に変更されます。

SUSPENDED タグ

テナントで使用されなくなったアカウントに使われます。アカウント内のすべてのリソースは削除されています。アカウントをリセットする方法はありません。つまり、これは以前のテナント情報が、アカウントにまだ残っていないことを保証する方法がないことを意味します。Suspended OU に移動されたアカウントは、決して再利用しないでください。

Suspended OU に含まれるアカウントは、依然として組織全体のアカウント数に含まれています。現在、プログラムでアカウントを削除する方法がないため、SUSPENDED タグの付いたアカウントを、手動で削除するワークフローを整備する必要があります。AWS Organizations CreateAccount API アクションで作成されたアカウントを手動で削除するには、ルートアカウントのパスワードをリセットし、そのアカウントにログインして、アカウントの削除をリクエストする必要があります。AWS Organizations に関連付けられた AWS アカウントの削除に関する詳細については、AWS アカウントの閉鎖をご参照ください。

SaaS アプリケーションの土台となる組織の中に、いくつのアカウント数があるかを把握することは重要なことです。組織内のアカウント数は、ListAccounts API アクションを使用して確認できます。アカウント数がアカウント制限に近づいている場合は、SUSPENDED タグの付いたアカウントを削除してください。

テナントのアカウントへのベースライン化

SaaS アプリケーションに新規テナントをオンボーディングする前に、テナントが使用するアカウントをプロビジョニングする必要があります。AWS Organizations API アクションを使ったアカウント作成のプロセスは数分で完了します。しかし、AWS エンタープライズサポートと最初のサービスクォータといったアカウントのベースラインを設定するプロセスは、数時間から数日かかる場合があります。いつでも新規テナント用に、ベースラインが設定されたアカウントをプロビジョニングできるわけではないため、プロビジョニング済みのアカウントをプールしておく必要があります。この数は、新規テナントをオンボーディングする頻度によって異なります。また SaaS プロダクトのティアごとに、異なるベースラインを検討する必要もありえます。例えば、エンタープライズティアのテナントに割り当てる AWS アカウントでは、ディベロッパーティアのテナントに割り当てるアカウントよりも、高いクォータが必要になることがあります。

AWS アカウントのプロビジョニング

アカウントをプロビジョニングするには、AWS Organizations CreateAccount API アクションを使います。アカウントを最初にプロビジョニングするときは、STATUS タグに BASELINING を設定して、Workload OU に配置する必要があります。アカウントのプロビジョニングプロセスには、数分かかる場合があります。アカウントが正常に作成されたら、AWS エンタープライズサポートを有効にします。

AWS エンタープライズサポートの有効化

AWS エンタープライズサポートには、多数のアカウントとそれらのアカウントの制限を、包括して管理するための役立つリソースが用意されています。

メンバーアカウントでエンタープライズサポートを有効にするには、まず管理アカウントで有効にする必要があります。AWS エンタープライズサポートが管理アカウントで有効になったら、Support API を使用して組織のメンバーアカウントにエンタープライズサポートをリクエストできます。AWS Organizations API を使うと、新規アカウントのアカウント番号を取得できます。次に Support API を使用して管理アカウントでサポートケースを作成し、メンバーアカウントのアカウント番号を AWS エンタープライズサポートに追加するようリクエストします。この新規アカウントが AWS エンタープライズサポートプランに追加されることで、このアカウント分のサポート費用が AWS エンタープライズサポートの費用に加算されます。

ブログ「Automating Service Limit Increases and Enterprise Support with AWS Control Tower」では、アカウントの作成時に、エンタープライズサポートを自動的に有効にする AWS Lambda 関数について説明しています。

サービスクォータ制限の設定

複数の AWS アカウントにわたってクォータを初期設定するには、少なくとも 2 つの方法があります。

もし設定する必要のあるクォータが 10 個以下で、組織内のすべてのアカウントで同じになる場合は、サービスクォータリクエストテンプレートを使用できます。AWS リージョン、サービス、および特定のクォータの新しい値を指定します。その後、リクエストテンプレートは AWS Organizations 内の組織に関連付けられます。新しいアカウントがプロビジョニングされると、組織のクォータが自動的に要求されます。

複数のリージョンにまたがって複数のクォータを設定する必要がある場合、リクエストテンプレートの上限である 10 項目だけでは不十分です。この場合は、Service Quotas API を使用してクォータの緩和をリクエストしてください。新しいクォータをリクエストする前に、GetServiceQuota API アクションを使用してクォータを確認してください。仮にオンデマンドスタンダードインスタンスの、現在の vCPU 制限を確認する場合は、次の AWS コマンドラインインターフェイス(AWS CLI)コマンドを使用して GetServiceQuota API コールを発行します。

$ aws service-quotas get-service-quota --service-code ec2 --quota-code L-1216C47A
{
    "Quota": {
        "ServiceCode": "ec2",
        "ServiceName": "Amazon Elastic Compute Cloud (Amazon EC2)",
        "QuotaArn": "arn:aws:servicequotas:us-east-1:111122223333:ec2/L-1216C47A",
        "QuotaCode": "L-1216C47A",
        "QuotaName": "Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances",
        "Value": 300.0,
        "Unit": "None",
        "Adjustable": true,
        "GlobalQuota": false,
        "UsageMetric": {
            "MetricNamespace": "AWS/Usage",
            "MetricName": "ResourceCount",
            "MetricDimensions": {
                "Class": "Standard/OnDemand",
                "Resource": "vCPU",
                "Service": "EC2",
                "Type": "Resource"
            },
            "MetricStatisticRecommendation": "Maximum"
        }
    }
}

この API コールに対するレスポンスには、Value キーが含まれます。Value キーの値は、現在のクォータを表しています。このクォータが不足している場合は、RequestServiceQuotaIncrease API アクションを使用して、プログラムによってクォータを緩和できます。例えば、テナントに対して実行するサービスをサポートするために、新規アカウントにデフォルトで 3,000 vCPU のクォータが必要であるとします。この場合、次のコマンドで RequestServiceQuotaIncrease API をコールします。

$ aws service-quotas request-service-quota-increase \
	--service-code ec2 \
	--quota-code L-1216C47A \
	--desired-value 3000

テナントの管理

クォータを緩和したら、その AWS アカウントは、利用可能なアカウントのプールに参加できます。これには STATUS タグを BASELINED に変更することが必要です。このタグが適用されると、テナントオンボーディングメカニズムは STATUS タグを ACTIVE に設定し、テナント ID を値として TENANT_ID タグを割り当てることで、このアカウントをテナントに割り当てることができます。

ベースライン化されたアカウントでテナントをオンボーディングする

SaaS ソリューションにおける新規テナントのオンボーディングプロセスの一環として、ベースラインが設定されたアカウントの 1 つを、テナントに割り当てる必要があります。これは割り当てられていないアカウントの STATUS タグを、BASELINED から ACTIVE に設定することで実現できます。TENANT_ID タグにも一意のテナント ID を設定する必要があります。アカウントをテナントに関連付けたら、SaaS アプリケーションに必要なインフラストラクチャをプロビジョニングし、アプリケーションをデプロイする必要があります。また、この新しいデプロイメントを SaaS アプリケーション内の共有リソースと統合する必要があります。この手順は SaaS アプリケーションごとに異なります。

メンバーアカウントのクォータを監視する

各 AWS アカウントのクォータは独立して設定されますが、テナントが加入しているティアに応じて一貫して設定する必要があります。例えば、最も低いティアの vCPU のクォータが 3,000 の場合、そのティアのテナントに割り当てられている他のすべてのアカウントにも、同じクォータが適用されているべきです。テナントごとの使用量によっては、特定のテナントアカウントでクォータを緩和する必要があります。リソース消費を監視し、特定のアカウントのクォータは適切なのか確認してみてください。

Amazon CloudWatch は、複数のアカウントとリージョンにまたがった監視ができます。CloudWatch のメトリクスアラームを各テナントアカウントに設定し、監視元のアカウントで利用できるようにすると、クォータの問題をすばやく認識できるようになります。

メンバーアカウントのクォータを監視するには、AWS Trusted Advisor、サービスクォータ、お客様独自のモニタリングの 3 つのメカニズムがあります。AWS Trusted Advisor は、Amazon RDS、Amazon EC2、Amazon EBS、Amazon DynamoDB などの一般的なサービスをサポートしています。Trusted Advisor の CloudWatch アラームを設定する方法については、ブログ「Monitoring Service Limits with Trusted Advisor and Amazon CloudWatch」をご参照ください。

現在、サービスクォータのツールによる使用率監視をサポートしているサービスの一覧については、サービスクォータの可視化とアラームの設定をご参照ください。これらのクォータに関する CloudWatch アラームを設定するには、サービスクォータと Amazon CloudWatch アラームをご参照ください。

もし AWS Trusted Advisor も、サービスクォータも、使用率のモニタリングをサポートしていない場合は、リソース使用率を、お客様が独自でモニタリングする必要があります。サービスクォータのツールは、現在のクォータの値を保持します。現在の使用率は、さまざまな AWS API を使用して計算できます。

例えば、Amazon ElastiCache でリージョンあたりの最大ノード数のクォータを監視する必要があるとします。サービスクォータも、AWS Trusted Advisor も、このクォータの監視をサポートしていません。Amazon EventBridge のスケジュールされたイベントを使い、Lambda 関数を定期的に実行することで、リージョンにプロビジョニングされたノードの数を監視できることがあります。この Lambda 関数は、ElastiCache DescribeCacheClusters API アクションと、Service Quotas GetServiceQuota API アクションをコールします。Lambda 関数はレスポンスのクラスター数をカウントし、PutMetricData API アクションを使用して、この情報を Amazon CloudWatch に格納します。加えて GetServiceQuota API コールが返す Value キーを使い、既存のクォータを追跡する別のメトリクスを格納します。

メトリクスの数式に基づくアラームを使用して、クォータを緩和するタイミングを確認できます。例えば、上記で計算した 2 つのメトリクスを使って、クォータの 80%を超えて使用されたタイミングを判断できます。詳細については、メトリクスの数式に基づく CloudWatch アラームの作成をご参照ください。このアラームは SNS トピックに通知を送信し、SNS トピックはアラーム情報を Lambda 関数に渡します。この Lambda 関数はアラーム情報を解析し、Service Quotas API を介してクォータの緩和をリクエストします。

アプリケーションのデプロイメントとの連携

アプリケーションの更新をデプロイする必要がある場合、すべてのアカウントのテナントのインフラストラクチャを更新する必要があります。プールモデルでは、更新すべきインフラストラクチャのセットは 1 つになりますので、一般に簡単なことです。しかし、各テナントに独自のインフラストラクチャのセットがある場合は、各テナントに更新を適用する必要があります。つまり 1,000 つのテナントがある場合、1,000 種類もの個別のインフラストラクチャを更新する必要があるということです。

組織内の各アカウントは、作成時に IAM ロールがプロビジョニングされます。この IAM ロールを使用することで、アプリケーション更新をアカウントに適用するための、特別なロールまたはロールセットを追加できます。必要な IAM ロールをアカウントにブートストラップした後、AWS Organizations がアカウントのプロビジョニング時に作成した IAM ロールを削除できます。データプレーンアカウントのこのロールを削除することで、管理者権限を持つ使わない IAM ロールを保持することを回避できます。

例えばアプリケーションが、複数の EC2 インスタンスをデプロイする CloudFormation テンプレートからデプロイされているとします。テンプレートをデプロイするために使うロールは、CloudFormation スタックを作成し、EC2 インスタンスを実行できる必要があります。使うロールは、アプリケーションのデプロイに必要な権限のみに制限されていなければなりません。

このプロセスは CI/CD パイプラインに統合できます。例えば、アプリケーション更新のデプロイ中に、AWS Organizations API から、テナントとそれに関連付けられた AWS アカウントの一覧を取得できます。そして、そのデプロイプロセスはテナントに割り当てられた AWS アカウントのロールを引き受け、デプロイを実行できます。これは一度に、あるいはバッチで実行できます。

テナントごとのコストの監視

このモデルでは、テナントが負担するコストの多くを簡単に測定できます。各テナントのアカウントは個別に請求書を作成します。AWS アカウントごとにテナントが 1 つしかないため、この請求書全体は 1 つのテナントのものであると考えることができます。

各アカウントで発生したコストは、組織の管理アカウントで確認できます。詳しくは、請求およびアカウントアクティビティをご参照ください。

テナントのオフボーディング

一度使用したテナントの AWS アカウントを、引き下げなければならない場合があります。テナントを初めて使い始めた状態に、AWS アカウントを初期化する確実な方法はありません。CloudFormation でインフラストラクチャをデプロイしたとしても、データやリソースが存続するリスクは依然として存在しています。

また今のところ、プログラムでアカウントを削除する方法はありません。AWS アカウントを削除するには、ルートアカウントにサインインし、アカウントの削除リクエストを送信します。保持しているアカウントの数とテナントの入れ替えによっては、これは煩わしい作業になりえます。このような理由から、AWS Organizations API を使って、アカウントのタグを変更し、Suspended OU に移動するべきです。

テナントが SaaS の利用をやめた際には、最初にアカウントを Suspended OU に移動し、STATUS タグを SUSPENDING に更新してください。その後、アカウント内のリソース(S3 バケット、CloudFormation スタック、請求コストが発生するその他のリソースなど)の削除を開始できるようになります。リソースが削除されたら、アカウントに関連付けられている STATUS タグを SUSPENDED に更新する必要があります。このアカウントは再利用しないでください。

ティア別の SaaS オファリングに関する考慮事項

SaaS プロバイダーは、しばしば自社のオファリングをティアごとにパッケージ化することで、さまざまな体験を顧客に提供しています。これには、無料版やトライアル版のような無償のサービスも含まれます。これらは、限られた機能または、全機能を限られた期間で提供するサブスクリプションです。無償のサービスを利用するすべての顧客が、有料のサブスクリプションに移行するわけではありません。課金していない顧客ごとに新規アカウントを割り当てると、最終的には、短期間しか使用されなかった非アクティブなアカウントがいくつも作成される可能性があります。

この問題を解決するには、課金していない顧客専用のアカウントを少なくとも 1 つ作成します。この共有アカウントには、同じアプリケーションのデプロイメントが複数含まれています。プールベースのモデルへの大規模なリファクタリングを避けるために、VPC-per-Tenant モデルを使う必要があります。VPC-per-Tenant が適用できない場合は、適切なサイロベースのモデルでアプリケーションをデプロイします。もしトライアル終了時に顧客が移行しなかった場合でも、AWS アカウントをサスペンドすることはありません。顧客が利用したリソースを削除するだけで済みます。

課金していない顧客向けに共有アカウントを持つことには、いくつかの欠点があります。もし顧客が有料の SaaS プランに変換した場合、無償アカウントの顧客のデータをどうするかを決めなければなりません。2 つの明らかな選択肢があります。

  • 顧客を無償アカウントから、顧客自身のアカウントにマイグレーションします。
  • この無償のオファリングは、本番環境として使用できないと顧客に伝えます。

最初の選択肢は、達成するためにかなり作り込んだツールが必要です。顧客のデータと設定を、BASELINED タグが付与されたアカウントの 1 つにマイグレーションする必要があります。2 つ目の方法は簡単ですが、最適な顧客体験であるといえない可能性があります。顧客が無償アカウントにサインアップする際には、必ず顧客と期待値の設定をするようにしてください。

もしアカウントに複数の無料ティアの顧客が含まれている場合は、そのアカウントの TENANT_ID に、FREE_TIER_ACCOUNTS のような値のタグ付けします。これにより、STATUS タグが ACTIVE に設定されている、TENANT_ID の定義されていないアカウントは存在しなくなります。

最後に、無料ティアのアカウントと、有料アカウントの分離の境界が異なることを、顧客に明確に伝えてください。

まとめ

SaaS アプリケーションでテナントごとに AWS アカウントを使用するには、他のテナント分離モデルでは必要とされないプランニングをする必要があります。プランニングの多くは、SaaS アプリケーション固有のものです。

この投稿では、Account-per-Tenant モデルを効率的に管理する方法を共有しました。このモデルをデプロイする際に、重点的に取り組むべき点と、 利用すべき AWS のサービスについて解説しました。この投稿の情報は、AWS アカウントでテナントを分離するための道筋の第一歩となるはずです。組織の作成と設定のチュートリアルに従って、AWS Organizations の検証ができます。

翻訳はパートナーソリューションアーキテクトの青嶋が担当しました。原文はこちらです。