paint-brush
AWS と CDK でマルチテナントの内外サービスを構築する形式 (パート 1): API ゲートウェイと AppSync に@filletofish
2,335 測定値
2,335 測定値

AWS と CDK でマルチテナントの内部サービスを構築する方法 (パート 1): API ゲートウェイと AppSync

Filipp Fediakov11m2023/09/19
Read on Terminal Reader

長すぎる; 読むには

このマルチテナント シリーズの第 1 回では、AWS での内部マルチテナント サービスの構築の複雑さを探ります。 AWS API Gateway と AppSync について詳しく説明し、テナントの分離、モニタリング、スケーリングなどの重要な側面をカバーします。実用的な洞察と例を使用して、マルチテナント アーキテクチャのセキュリティを確保し、最適化するためのベスト プラクティスを見つけてください。
featured image - AWS と CDK でマルチテナントの内部サービスを構築する方法 (パート 1): API ゲートウェイと AppSync
Filipp Fediakov HackerNoon profile picture
0-item



このブログ投稿シリーズでは、 AWSでマルチテナント サービスを構築するためのベスト プラクティスについて説明したいと思います。マルチテナントサービスの構築方法に関する既存の文献は、通常、数百の顧客を持つ SaaS アプリケーションを対象としています (例: )。


このシリーズの主な根拠は、すべて AWS アカウントにデプロイされるクライアント数が少ないユースケース向けのマルチテナント サービスの構築に聚焦点を当てることです。常、これは内部结构实用のためにマルチテナント サービスを構築するシナリオに当てはまります。


一連のブログ投稿を、サービス間の統合の種類 (同期、非同期、バッチ統合) ごとに 3 つの部分に分割します。


パート 1 では、API Gateway と AppSync という 2 つの AWS サービスのマルチテナント アーキテクチャについて説明します。記事全部を通じて、Typescript と AWS CDK でこの記事用に構築されたサンプル アプリケーション アプリのコードを根据します: 。


コンテンツの概要

  1. 内部サービスのマルチテナント

    1.1.テナントの分離1.2.マルチテナント監視1.3.スケーリング
  2. 内部サービスのマルチテナント

    2.1.テナントの分離 - アクセス制御2.2 テナントの分離 - 騒音の多い隣人の問題2.3 マルチテナント監視2.4 メトリクス、アラーム、ダッシュボード2.5 API クライアントのオンボーディングとオフボーディング
  3. AWS AppSync によるマルチテナンシー

  4. 結論

1. 内部サービスのマルチテナント


マルチテナンシーとは、ソフトウェアの単一インスタンスで複数の顧客またはテナントにサービスを提供するソフトウェアの機能です。


複数のチームがサービスAPIを呼び出すことを許可すると、サービスはマルチテナントになります。マルチテナント アーキテクチャでは、テナントの分離、テナント レベルの監視、スケーリングなど、サービスがさらに複雑になります。


社内マルチテナントサービスの例


1.1.テナントの分離

通常に、テナントの分離では、テナントが別のテナントのリソースにアクセスできないようにすることで、セキュリティの問題に対処します。また、1 つのテナントによって引き起こされた障害がサービスの他のテナントに影響を与えないように、テナントの分離が実装されています。これは、騒々しい隣人問題とも呼ばれることがよくあります。詳細については、テナント分離戦略に関する AWS ホワイトペーパーをご覧ください。


1.2.マルチテナント監視

複数のテナントがインフラストラクチャ リソースの共得を開始したら、各テナントがシステムをどのように动用するかを監視する相应があります。これは常、テナント名または識別子がログ、メトリクス、ダッシュボードに存有する相应があることを预示します。マルチテナント監視は、次のようないくつかの正当理由で役立ちます。


  1. 問題のトラブルシューティング: 問題の特定と解決を簡素化し、テナント固有の問題と広範な問題を区別します。
  2. リソースの割り当てとキャパシティ プランニング。マルチテナントの監視は、リソース割り当てと容量計画のためにテナントごとのリソース消費を追跡するのに役立ちます。サービスがサーバーレスであっても、近いうちに AWS の制限に達するかどうかを理解するには、クライアントのリソース消費を理解する必要があります (典型的な例は Lambda 関数の同時実行制限です)。
  3. SLA 管理: SLA に対するテナント固有のパフォーマンスの追跡を可能にします。
  4. 請求する。内部サービスの使用に対して他のチームに請求を開始する可能性は低いです。ただし、企業の成長がある程度の規模になると、サービスを倹約的に使用するために他のチームに請求することが良いアイデアになる可能性があります。


1.3.スケーリング

マルチテナント サービスは、シングルテナント サービスよりもスケーリングの課題にさらされる风险性が高くなります。ただし、スケーラビリティは大きなトピックなので、このブログ期刊投稿では取り上げません。


2. APIゲートウェイによるマルチテナント

AWS でREST 、HTTP、または WebSocket API を使用して AWS Web サービスを構築している場合は、API Gateway を使用している可能性が高くなります。


2.1.テナントの分離 — アクセス制御

AWS では、サービスのリソースとデータを分離し、コスト操作を很容易にし、テスト環境と本番環境を分離するために、各サービスを孤身一人の AWS アカウントにデプロイすることをお勧めします (詳細については、 を图案填充してください)。


会社のサービスが AWS にデプロイされている場合、API ゲートウェイへのアクセスを维护するための最も搞清楚なソリューションは AWS IAM です。 AWS Cognito は、マルチテナント API へのアクセスを维护するためのもう 1 つのオプションです ( 、 」を参照物)。


AWS IAM と AWS Cognito の比較については、別途詳しく説明する価値があります。ただし、この記事では、会社のサービスが AWS にある場合にアクセスを管理工作する最も簡単な做法である AWS IAM を操作することにします。


API ゲートウェイ メソッドの AWS IAM 認証を有効にすると ( を根据)、このメソッドのすべての API リクエストは、API ゲートウェイの呼び出しを許可された IAM ID の認証情報で摘要される需要があります。


デフォルトでは、AWS アカウント間のアクセスは許可されません。たとえば、別の AWS アカウントの認証情報を利用して API Gateway を呼び出すと失敗します。顧客を API に統合するには、クロスアカウント アクセスを設定する必需があります。 API Gateway へのクロスアカウント アクセスを許可するには、リソースベースの認可 (API Gateway HTTP API では利用できません) と ID ベースの認可 (詳細はを参照物) の 2 つの方式を利用できます。):


  1. リソースベースの認証を使用したクライアントのオンボーディング。リソースベースのアクセスの場合、API ゲートウェイ リソース ポリシーを更新し、クライアントの AWS アカウントを追加する必要があります。この方法の主な欠点は、リソース ポリシーを更新した後、変更を有効にするために API Gateway ステージを再デプロイする必要があることです (AWS ドキュメントおよびを参照)。ただし、CDK を使用すると、新しいステージのデプロイを自動化できます ( を参照)。もう 1 つの欠点は、リソース ポリシーの最大長の制限です。


  2. ID ベースの認証を使用したクライアントのオンボーディング。 ID ベースのアクセス制御の場合、クライアントの IAM ロールを作成し、ロールのリソース ポリシー (信頼関係) を更新することでクライアントがそのロールを引き受けられるようにする必要があります。 IAM ユーザーを使用することもできますが、セキュリティの観点からは IAM ロールの方が優れています。ロールでは一時的な認証情報を使用した認証が可能であり、IAM ユーザー認証情報を保存する必要はありません。アカウントごとに 1,000 ロールという制限がありますが、この制限は調整可能です。さらに、API へのクロスアカウント アクセスを取得するためのロールベースの方法のもう 1 つの欠点は、新しい API クライアントごとに IAM ロールを作成する必要があることです。ただし、ロール管理は CDK を使用して自動化できます ( を参照)。



AWS IAM 認証では、API ゲートウェイへのアクセスのみを制御できます (IAM ポリシーを使用して、どの AWS アカウントがどの API ゲートウェイ エンドポイントを呼び出すことができるかを指定できます)。データおよびサービスのその他の基盤となるリソースへのアクセス制御を実装するのはあなたの責任です。サービス内では、API ゲートウェイ リクエストで渡される呼び出し元の AWS IAM ARN を使用して、さらにアクセス制御を行うことができます。


 export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { // IAM Principal ARN of the api caller const callerArn = event.requestContext.identity.userArn!; // .. business logic based on caller return { statusCode: 200, body: JSON.stringify({ message: `Received API Call from ${callerArn}`, }) }; };



2.2.テナントの分離 — 騒音の多い隣人の問題

デフォルトの API ゲートウェイ制限は 10,000 TPS ( ) です。ただし、ダウンストリームの依存関係により、サービスではより低い TPS 制限が这个必要性になる場合があります。システム全员の能用的 性に影響を与える、単一のテナントからの API リクエストの過負荷を逃避するには、テナントごとの API レート制限 (「スロットル」または「アドミッション コントロール」とも呼ばれます) を実装する这个必要性があります。


API Gateway API 便用プランとキーを便用して、各クライアントの制限を個別に設定できます (詳細については、AWS ドキュメント [1]、[2]、および [3] を根据してください)。


2.3.マルチテナント監視

API Gateway には 2 種類のログがあります。

  1. API ゲートウェイ実行ログ: リクエストまたはレスポンスのパラメータ値、必备な API キー、用到量プランが有効かどうかなどのデータが含まれます。デフォルトでは有効になっていませんが、構成することができます。


  2. API ゲートウェイのアクセス ログ機能: API にアクセスしたユーザー、アクセス方法步骤、アクセスされたエンドポイント、および API 呼び出しの結果をログに記録できます。ログ组织形式を指定的し、コンテキスト変数を选择してログ知识を選択できます (CDK のドキュメントを对比)。


API クライアントのリクエストを監視するには、アクセス ログを有効にすることをお勧めします。少なくとも、呼び出し元の AWS IAM ARN ( $context.identity.userArn )、リクエスト パス ( $context.path )、サービス応答ステータス コード$context.status 、および API 呼び出しレイテンシー ( $context.responseLatency ) をログに記録できます。 。


個人的には、AWS IAM 認証とコンピューティングとしての Lambda 機能を備えたサービスの場合、次の API ゲートウェイ アクセス ログ設定が役立つことがわかりました。
 const formatObject = { requestId: '$context.requestId', extendedRequestId: '$context.extendedRequestId', apiId: '$context.apiId', resourceId: '$context.resourceId', domainName: '$context.domainName', stage: '$context.stage', path: '$context.path', resourcePath: '$context.resourcePath', httpMethod: '$context.httpMethod', protocol: '$context.protocol', accountId: '$context.identity.accountId', sourceIp: '$context.identity.sourceIp', user: '$context.identity.user', userAgent: '$context.identity.userAgent', userArn: '$context.identity.userArn', caller: '$context.identity.caller', cognitoIdentityId: '$context.identity.cognitoIdentityId', status: '$context.status', integration: { // The status code returned from an integration. For Lambda proxy integrations, this is the status code that your Lambda function code returns. status: '$context.integration.status', // For Lambda proxy integration, the status code returned from AWS Lambda, not from the backend Lambda function code. integrationStatus: '$context.integration.integrationStatus', // The error message returned from an integration // A string that contains an integration error message. error: '$context.integration.error', latency: '$context.integration.latency', }, error: { responseType: '$context.error.responseType', message: '$context.error.message', }, requestTime: '$context.requestTime', responseLength: '$context.responseLength', responseLatency: '$context.responseLatency', }; const accessLogFormatString = JSON.stringify(formatObject); const accessLogFormat = apigw.AccessLogFormat.custom(accessLogFormatString);


ログ記録を有効にすると、CloudWatch Insights を操作して、選択した API クライアントからの全新の呼び出しを次のように簡単に作为できます。
 fields @timestamp, path, status, responseLatency, userArn | sort @timestamp desc | filter userArn like 'payment-service' | limit 20


2.4.メトリクス、アラーム、ダッシュボード

API Gateway によってデフォルトでサポートされている CloudWatch メトリクスは、すべてのリクエストに対して集約されます。ただし、API Gateway のアクセス ログを解析して、クライアント名の追加ディメンションを使用してカスタム CloudWatch メトリクスを公開し、クライアント (テナント) の API の使用状況を監視することができます。少なくとも、クライアントごとの CloudWatch メトリクス Count、4xx、5xx、 Dimension=${Client}で分割された Latency を公開することをお勧めします。ステータス コードや API パスなどのディメンションを追加することもできます。


2.4.1.クライアントごとのメトリックを公開するためのメトリック ログ フィルターの使用


CloudWatch メトリクス ログ フィルタ (ドキュメントを符合) を动用すると、カスタム フィルタを提供数据し、API ゲートウェイ アクセス ログからメトリクス値を空出来できます (下の例を符合)。メトリック ログ フィルターを动用すると、ログからカスタム メトリック ディメンションの値を空出来することもできます。マルチテナント監視の場合、ディメンション Client は呼び出し元の IAM ARN になる也许性があります。


メトリック ログ フィルターの主な利点は、(1) 管理系统するコンピューティングが不可 (2) シンプルで安価であることです。ただし、データの変更 (IAM ARN の代わりに、より読みやすいクライアント名を設定するなど) を行うことはできず、単一ログ グループあたりのメトリック フィルターの数は 100 個までという制限があります (ドキュメント)。


ディメンションClientPathを使用してCountを公開するための CloudWatch メトリクスログフィルターの例

new logs.MetricFilter(this, 'MultiTenantApiCountMetricFilter', { logGroup: accessLogsGroup, filterPattern: logs.FilterPattern.exists('$.userArn'), metricNamespace: metricNamespace, metricName: 'Count', metricValue: '1', unit: cloudwatch.Unit.COUNT, dimensions: { client: '$.userArn', method: '$.httpMethod', path: '$.path',},}); });


操作してください。


2.4.2. Lambda 関数を使用してクライアントごとのメトリクスを公開する

別のオプションは、ログを解密し、メトリクスを提取して公開する Lambda 関数を作为することです。これにより、不知道なクライアントをフィルタリングしたり、userArn からクライアント名を提取したりするなど、より多くのカスタム作業を行うことができます。


わずか数行の CDK コードを食用して、Lambda 関数を API ゲートウェイ アクセス ログにサブスクライブします。


 const logProcessingFunction = new lambda.NodejsFunction( this, 'log-processor-function', { functionName: 'multi-tenant-api-log-processor-function', } ); new logs.SubscriptionFilter(this, 'MultiTenantApiLogSubscriptionFilter', { logGroup: accessLogsGroup, destination: new logsd.LambdaDestination(logProcessingFunction), filterPattern: logs.FilterPattern.allEvents(), });


の是完全な例との実装を符合してください。


使用状況キーと Lambda 関数を追加してクライアントごとのメトリクスを公開する



クライアントごとに裁切された API Gateway メトリクスの公開を開始すると、クライアントごとに CloudWatch ダッシュボードと CloudWatch アラームを個別に做成できるようになります。



CloudWatch ダッシュボードのクライアントごとのメトリクスの例



2.5. API クライアントのオンボーディングとオフボーディング

CDK アプリは、クライアント名、その AWS アカウント、请求された TPS 制限、その他のメタデータを含む構成を保持するための簡単なソリューションとなる可以性があります。新しい API クライアントをオンボードするには、コードで监管されている構成にそれを追加する有需要があります。


 interface ApiClientConfig { name: string; awsAccounts: string[]; rateLimit: number; burstLimit: number; } const apiClients: ApiClientConfig[] = [ { name: 'payment-service', awsAccounts: ['3','444455556666'], rateLimit: 10, burstLimit: 2, }, { name: 'order-service', awsAccounts: ['777788889999'], rateLimit: 1, burstLimit: 1, }, ];


この設定を食用して、CDK アプリは IAM ロール、API ゲートウェイ食用キーを做成し、アクセス ログを解析视频する Lambda 関数にクライアントの名前を渡すことができます (サンプル アプリケーション コードを操作)。


3. AWS AppSync によるマルチテナンシー

サービスにGraphQL API がある場合は、おそらく AppSync を使用するでしょう。 API Gateway と同様に、IAM 認証を使用して AppSync リクエストを承認できます。 AppSync にはリソース ポリシーがないため ( を参照)、AppSync API へのアクセス制御を設定するにはロールベースの承認のみを使用できます。 API Gateway と同様に、サービスの新しいテナントごとに個別の IAM ロールを作成します。


残念ながら、AppSync では、テナントの分離と監視に必须なクライアントごとの調整のサポートが制限されています。 WAF を选用して AppSync の TPS 制限を設定することはできますが、サービス テナントを分離するためにクライアントごとに個別の制限を做成することはできません。同様に、AppSync は API Gateway のようにアクセス ログを给予しません。


解決? API Gateway をプロキシとして AppSync に追加し、上記の API Gateway 機能をすべて用到して、テナントの分離や監視などのマルチテナント要件を実装できます。さらに、AppSync にはまだ会出现しない Lambda オーソライザー、カスタム ドメイン、API ライフサイクル方法などの他の API ゲートウェイ機能を用到できます。欠点は、リクエストのレイテンシーが许多増加することです。




API Gateway を使用した AppSync へのリクエストのプロキシ


4. 結論

それでおしまい。ご質問やアイデアがございましたら、コメント欄でお知らせいただくか、会直接私にご連絡ください。このシリーズの次のパートでは、AWS Event Bridge および AWS SQS / SNS との非同时外部統合のベストプラクティスを確認します。


AWS 上にマルチテナント サービスを構築するというトピックを深く掘り下げたい場合は、次のリソースが役立つことがわかりました。




바카라사이트 바카라사이트 온라인바카라