Amazon Web Services ブログ

Amazon RDS Proxy によるマルチテナント型 SaaS データベースのプロキシソリューションの構築と負荷テスト

このブログは「Build and load test a multi-tenant SaaS database proxy solution with Amazon RDS Proxy」を翻訳したものです。

AWS 上で SaaS を提供する多くのお客様は、マルチテナントやテナントの分離に慣れ親しんでいます。実際に MySQL を利用するお客様には、各テナントがそれぞれ独立したデータベースやスキーマにアクセスする、マルチテナントのブリッジモデルを採用している方もいます。AWS はマルチテナントを始めるためのツールやベストプラクティスを数多く用意していますが、頻繁な同時接続によりタイムアウトやレイテンシーが発生する場合など、大規模なデータベースでのテナントの分離が課題になることがあります。

Amazon RDS Proxy は、アプリケーションをよりスケーラブルに、よりセキュアに、よりデータベース障害に強くする、フルマネージドで可用性の高いデータベースプロキシです。この投稿では初めの 2 つの利点、つまりデータベース接続のプーリングと共有によるスケーラビリティの向上、AWS Identity and Access Management (IAM) 認証と AWS Secrets Manager 利用によるセキュリティ向上に注目します。またこの投稿では、Amazon Aurora レプリカに接続する RDS Proxy のリーダーエンドポイントを使います。Amazon Aurora MySQL 互換エディションによるマルチテナントを用いますが、Amazon Relational Database Service (Amazon RDS) と Aurora の MySQL/PostgreSQL いずれにおいても、シングルテナントとマルチテナントのデータベースに RDS Proxy が利用できます。

この投稿では、Aurora の MySQL 互換エディションと、RDS Proxy を使ったアーキテクチャのマルチテナント展開について説明します。テナントの分離について Aurora を用いて説明し、負荷テストの結果を RDS Proxy を使わない場合と比較することで、RDS Proxy の有効性を検証します。この投稿にはデモのリソースを再現するための AWS CloudFormation テンプレートが含まれています。

この投稿を読み進めることで、マルチテナントのデータベースのプロキシソリューションを構築して負荷テストを行い、ビジネスに関連するメトリクスを比較できるようになります。また、Aurora と RDS Proxy で IAM 認証を使う方法を学び、AWS LambdaAmazon CloudWatchAmazon API GatewayAWS X-Ray、および Secrets Manager の知識を深めることができます。

ソリューションの概要

このソリューションは、次のアーキテクチャ図のように 3 つの Amazon Virtual Private Cloud (Amazon VPC) で構成されています。

3 つの VPC は次のようになります。

  • プロキシ有りの VPC:この VPC には、Lambda、RDS Proxy、Aurora、そして Secrets Mangerに接続する Amazon VPC エンドポイントが含まれており、これらを組み合わせることでスケールするマルチテナントなアクセスレイヤーを構築できます。ここにはテナントのデータアクセスを処理する、Node.js または Python の Lambda関数が含まれています。AWS Security Token Service (AWS STS)、IAM ロール、および IAM セッションポリシーを使って、各テナントに、正しいデータベースまたはスキーマへの接続が提供されます。Aurora クラスタには 3 つのインスタンスがあります。1 つのライターと 2 つの Aurora レプリカ(デフォルトでは db.r5.large インスタンスクラス)があり、負荷テストに使う RDS Proxy のリーダーエンドポイントの後ろに配置されます。
  • プロキシ無しの VPC:この VPC は、RDS Proxy と Secrets Manager が無い以外はプロキシ有りのVPC と同じアーキテクチャです。つまり、Lambda 関数は RDS Proxy のリーダーエンドポイントではなく、Aurora のリーダーエンドポイントを直接呼び出します。
  • 負荷テスト用の VPC:この VPC では、オープンソースのPython 製分散負荷テストツールである Locust を使います。プライマリワーカー構成の Amazon Elastic Compute Cloud (Amazon EC2) に Locust をインストールして、プロキシ有りと プロキシ無しのVPC へ同時にリクエストを送信してパフォーマンスを比較します。これらのインスタンスは API Gateway にリクエストを送り、API Gateway はこのリクエストを、プロキシ有りとプロキシ無しの VPC に転送します。

またこのアーキテクチャには、負荷テストのリソースをモニタリングするための共有サービスとして、X-Ray、CloudWatch、Amazon RDS Performance Insights、Locust ダッシュボードが含まれています。

これらの VPC を組み合わせることで、アーキテクチャを展開し、その利点を目で確認することができます。また、この CloudFormation テンプレートは、プロキシ有りの VPC のみをデプロイして、スタンドアロンの RDS Proxy とアクセスレイヤーを作成することもできます。

このソリューションをデプロイして実行するために、次のことを行います。

  1. CloudFormation テンプレートをデプロイし、Locust ダッシュボードに接続する。
  2. ソリューションのテナントの分離を説明する。
  3. 負荷テストを行い、ダッシュボード、CloudWatch、X-Ray を使って、結果を分析します。

前提条件

このウォークスルーでは、次のものをご用意ください。

  • AWS アカウント
  • Lambda と、Python または Node.js の基本的な知識。
  • MySQL のマルチテナントに関する知識(このトピックおよびその他のデータパーティショニングのトピックの詳細については、パーティション分割をご覧ください)。

この CloudFormation テンプレートは、3 つの Amazon VPC、3 つのインターネットゲートウェイ、そして 3 つの Elastic IP アドレスを作成します。多くのリージョンでこれらのデフォルトのクォータは 5 つなので、既存の VPC が少ないリージョン、あるいは全てのクォータが緩和されたリージョンにデプロイすることをおすすめします。これらのクォータの詳細については、Amazon VPC クォータをご覧ください。ここでは説明のために 3 つの VPC を作成しますが、 現実のシナリオではこの数は減らすことができます。

負荷テスト用の VPC とプロキシ有りの VPC は負荷テスト専用ですので、テストが終了したら削除してください。プロキシ有りの VPC のリソースは、リファレンスとなるアクセスレイヤーを提供し、負荷テスト用の VPC やプロキシ有りの VPC を削除しても維持できますが、認可や認証などの本番環境で必要な機能は、どのレイヤーにも含まれていません(この実装方法の詳細については、「Managing SaaS Identity Through Custom Attributes and Amazon Cognito」をご覧ください)。本番環境で注意すべきその他の要素については、この投稿の最後に取り上げます。

CloudFormation テンプレートをデプロイする

Launch Stack を選択してテンプレートをデプロイしてください。

スタックのパラメータ、サポートされているリージョン、コストの内訳、使用されるすべてのコードなど、スタックに関する詳しい情報は GitHub リポジトリで確認できます。デプロイする前に、README ファイルを読むことをおすすめします。

この CloudFormation テンプレートの主要なパラメータの 1 つに、Create Load Test Stack があります。True の場合、必要なすべての IAM ロール、Amazon EC2 セキュリティグループ、VPC サブネット、負荷テスト用に Locust を実行している Amazon EC2 のスポットフリートなど、アーキテクチャ上のすべてのコンポーネントがデプロイされます。また、プロキシ有りとプロキシ無しのデータベースに対して、Secrets Manager シークレットとダミーデータを作成します。

このパラメーターは、デフォルトでは True です。False に設定すると、テンプレートはアーキテクチャ図のプロキシ有りの VPC のみをデプロイし、最小限のアクセス権限になるよう、すべての IAM ロール、Amazon EC2 セキュリティグループ、VPC サブネットを作成します。このパラメータを False に設定するとダミーデータがデータベースに追加されないため、代わりに独自の MySQL データを追加することができます。一方で、パラメーターを True に設定すると、両方のデータベースにダミーデータが追加されるため、このブログを参考にしながら簡単に負荷テストができます。Launch Stack ボタンを選択すると、負荷テスト用のスタックの有無にかかわらず、プロキシ有りの VPC を自分の AWS アカウントにデプロイできます。

このテンプレート(負荷テスト用のスタックもデプロイする場合)は、プロキシ有りとプロキシ無しのデータベース両方にダミーデータを作成します。デフォルトでは 200 個のテナント(MySQL の文脈では 200 ユーザー)と、200 個のデータベース(テナントごとに 1 つのデータベース)を作成します。また、デフォルトで 200 個の Secrets Manager シークレットを作成します。これは、1 つの RDS Proxy に関連付けることができる最大数です(後述)。各データベースに 1,000 行のテーブルを作成し、各行はランダムな整数で埋められます。これは、両方のクラスターで作成される Aurora ライターインスタンスを使います。クラスターごとに 2 つの Aurora レプリカも作成され、負荷テスト用の VPC から、プロキシ有りの VPC の RDS Proxy のリーダーエンドポイントと、 プロキシ無しの VPC の Aurora リーダーエンドポイントの両方に SELECT ステートメントを送信してクラスターを比較します。

プロキシ無しの VPC の場合、テンプレートはパスワードの代わりに AWS 認証トークンを使ってテナントを作成します。これは、IAM とシームレスに連携してユーザーとテナントを認証する AWS が提供するプラグインを使います。詳細については、「IAM 認証を使用したデータベースアカウントの作成」をご覧ください。テナントのデータにアクセスするとき、Lambda 関数(アーキテクチャ図を参照)が AWS STS の AssumeRole を呼び出して、自身のデータベースのみアクセスできる  IAM のセッションポリシーを動的に作成できるようにしています。これは、ポリシーのリソースコンポーネント内でテナント ID を指定することで実現しています。詳細は、「IAM データベースアクセス用の IAM ポリシーの作成と使用」をご覧ください。

プロキシ有りの VPC でも IAM 認証を使いますが、Lambda と RDS Proxy 間の接続(Lambda と Aurora レプリカ間の直接接続ではなく)で使われます。ここでの違いは、RDS Proxy がテナント ID を取得し、Secrets Manager に安全に保存されたそのテナントのパスワードを取得する点です。RDS Proxy は、ネイティブ認証(IAM を使用しないユーザー名とパスワード)を使って、ウォームコネクションプールを介して Aurora レプリカへの接続を確立します。したがって、プロキシ有りのデータベースの場合、テンプレートはランダムに生成されたパスワードを使ってユーザーを作成し、これらの認証情報をユーザーごとに 1 つずつ Secrets Manager に保存します。

デプロイ後、CloudFormation コンソールの Outputs タブに移動し(View nested オプションを選択解除すると、rds-proxy-load-test という名前のメインスタックを見つけるのがとても簡単になります)、LocustAddress の値を見つけて、Web ブラウザーで URL を開きます。これにより、次のスクリーンショットのような Locust ダッシュボードに移動します。

Number of total users to simulateSpawn rate には任意の値を設定できますが、初めはそれぞれ 1,000 と 10 にすると良いでしょう。初めからより大きい Lambda の同時接続数にしない限り、これらの値にすることがおすすめです。また、もし 7,500 ユーザー以上にしたい場合は、スタックパラメータ Locust Worker Instances の値を増やすと良いでしょう。ユーザー数が増えると、プロキシ有りとプロキシ無しのデータベースの差が大きくなる傾向があり、Lambda のデフォルトのクォータによる Lambda のスロットリングが発生する可能性も高くなります。Lambda のクォータの詳細については、「Lambda クォータ」をご覧ください。次のように定義します。

  • Number of total users to simulate: 生成後、同時にテストに用いるユーザーの数です。ここのユーザーとは、ランダムなテナントにリクエストして数秒待つことを繰り返すエンティティです。この場合、ユーザーとは継続的に API リクエストを行うボットであると見なすことができ、データベースを分離するための 200 個のテナントや MySQL ユーザーとは大きく異なります。
  • Spawn rate: ユーザーの総数が指定した総数と等しくなるまで、シミュレーションのために毎秒追加するユーザー数です。たとえば、1,000 と 10 を指定すると、毎秒 10 人のユーザーが追加され、100 秒後には全部で 1,000 ユーザーがシミュレートされます。

Host については、CloudFormation コンソールの Outputs タブから APIGatewayURL の値を入力します。

負荷テストを始める前に、アーキテクチャのテナントの分離について説明します。

テナントの分離の説明

テンプレート(負荷テスト用のスタック)をデプロイすると、データベースにダミーデータが作成されます。CloudFormation コンソールの Outputs タブから、作成した Lambda 関数の名前(NoProxyLambdaName)を見つけ、AWS マネジメントコンソールから Lambda に移動してデプロイした関数を選択します。テナントのデータにアクセスするためのコードが表示されます。この投稿では Node.js を使用していますが、Python でも手順は同じです。このコードは次のように動きます。

  1. テナントからテナント ID を抽出する。
  2. AWS STS を使用してデータベーストークンを生成する。
  3. このトークンをパスワードとして使用して、Aurora クラスタまたは RDS Proxy に接続する。

このコードの大部分では、MySQL2 の Node.js パッケージを使って標準的な呼び出しをしています。この投稿では、クエリとマルチテナントに関連する箇所を取り上げます。

  var query = `SELECT * FROM mytable2 WHERE ID IN ${where_clause};`;

  // tenant id
  var tenant_id = event.queryStringParameters.tenant;
  var dbUser = user_name + tenant_id;
  // var dbUser = 'user100';

  // database
  var database = database_name + tenant_id;
  // var database = 'user_database100';

  // resource name
  var resource = cluster_endpoint_resource + tenant_id;
  // var resource = 'arn:aws:rds-db:' + dbRegion + ':' + accountId + ':dbuser:*/user100';

このコードの user は MySQL ユーザーまたはテナントを指します。最初の行では、SELECT ステートメントを使用して、データベースからテナントに関連する 5 行のデータを 1,000 行のデータからランダムに収集しています。tenant_iddatabaseresource_name の各箇所では、関数に渡された tenant_id パラメーターを抽出しています。この例では、これは 0~199 の整数です。ここではテナント ID を抽出して、関連するデータベースとアクセスするリソースをマッピングしています。たとえばテナント 100 が情報をリクエストした場合、このコードは値 100 を抽出して database100 を選択し、そのテナントが選択したデータベースにのみアクセスできるよう IAM セッションポリシーを動的に作成します。

関数のページで Test タブを選択して関数をテストするには、Lambda のテストイベントを設定する必要があります。テンプレートはデフォルトのままにし、イベント名に名前を指定して、イベントに以下をコピーしてください。

{ "queryStringParameters": { "tenant": "100" } }

Save を選択して Test を選択します。この関数が正常に実行され、データベースから 5 つのランダムな行が取得されるはずです。

上図のスクリーンショットを見ると、1~1,000 の ID から 5 つのランダムな行が選択され、各行の A~E 列には 5 つのランダムな整数値が含まれています。テナントの分離の境界を実際に確認するには、Code タブを選択して index.js ファイルに戻り、//var dbUser//var database//var resource で始まる行をアンコメントして、それぞれのすぐ上の行をコメントアウトします。アンコメントした行の末尾の数字を編集して、テナント ID が一致しないようにします。たとえば、次のようにします。

  // tenant id
  var tenant_id = event.queryStringParameters.tenant;
  // var dbUser = user_name + tenant_id;
  var dbUser = 'user100';

  // database
  // var database = database_name + tenant_id;
  var database = 'user_database101';

  // resource name
  // var resource = cluster_endpoint_resource + tenant_id;
  var resource = 'arn:aws:rds-db:' + dbRegion + ':' + accountId + ':dbuser:*/user100';

テナント 100 が、テナント 101 の所有するデータベースに、テナント 100 の権限でアクセスしようとするコードに変更されました。この関数をデプロイしてテストすると、実行に失敗し、次のエラーメッセージが表示されます。

  "statusCode": 500,
  "body": "Internal Server Error"

ログを下にスクロールすると、この原因となった具体的なエラーが表示されます。

INFO	Error: Access denied for user 'user100'@'%' to database 'user_database101'

これはつまり、テナントが異なるテナントのデータにアクセスすることを禁止されているということです。他のテナント ID の組み合わせ(0~199)を試すことで、3 つの ID がすべて一致しない限り、テナントのアクセスが拒否されることを確認できます。次の節へ進む前に、コードを元の形式(最初のコードスニペット)に戻し、Deploy を選択してください。

負荷テストを実行する

ここまで説明に沿って、負荷テストに必要なスタックをデプロイし、Locust のダッシュボードで Number of total users to simulateSpawn rateHost の値を指定してきました。Start swarming を選択して負荷テストを開始すると、上部バーのユーザー数が増加するはずです。

テナント ID は、Locust によって行われる API リクエストの末尾にクエリ文字列として渡され、Lambda 関数がそれを使って、テナント ID に一致するデータベースへのアクセスを制限および許可します。負荷テストの間、数秒ごとに各 Locust ユーザーはランダムにテナント ID を取得し、プロキシ有りとプロキシ無しの VPC をランダムに選択し、選択したテナント ID に関連する API エンドポイントを呼び出します。

プロキシ有りとプロキシ無しのエンドポイントは、それぞれ 50% の確率で選択されるため、リクエスト数はそれぞれ同程度に増加するはずです。次のスクリーンショットの右上に、秒間リクエスト数(RPS)が表示されています。1,000 ユーザーをシミュレートすると、この数は約 120 に達し(異なることもあります)、2 つのエンドポイント間でエラーの差が生じます。これらは、ダッシュボードの # Fails 列に表示されます。

また、ミリ秒単位で表示される Median、90%ile、Average といったレスポンスタイムに関しても大きな違いが見られるはずです。

結果の分析

X-Ray コンソールでサービスマップに移動すると、結果がより詳細に表示されます。

X-Ray は、ユーザーのリクエストがアーキテクチャ内を通過する様子をトレースします。上図のスクリーンショットから、プロキシ有りの VPC と比較して、プロキシ無しの VPC のエラーとレスポンスタイムが大きいとわかります。エラーの詳細を確認するには、no_proxy_stage の API Gateway に対応する円を選択し、右側のパネルで Fault のチェックボックスを有効にして、Analyze traces を選択します。

ここではリクエストのレスポンスタイムの分布、時系列のアクティビティ、およびトレースデータが表示されています。このページでは、これらのエラーはすべて HTTP ステータスコード 500 に起因しており、前節で変更した Lambda 関数の出力と同様であることを示しています。ページの一番下までスクロールすると、次のスクリーンショットのようなトレースリストが表示されます。

これらはクライアントに返されたレスポンスです。Lambda の CloudWatch Logs を表示すると、元となるエラーメッセージが確認でき(Monitor を選択し、No Proxy の Lambda コンソールの View logs in CloudWatch を選択すると、これらのメッセージを含むログストリームが表示されます)、プロキシ無しのデータベースで次のようになっていることがわかります。

Access denied for user 'user100'@'10.0.0.0' (using password: YES)

これにより、蓄積されたエラーは認証のタイムアウトによるもので、アクセス拒否エラーの原因となっていたことがわかります。このアクセス拒否エラーは、IAM 認証を使用してデータベースインスタンスに直接接続することで、追加のリソースを消費するために発生する現象です。MySQL で IAM 認証を使用する場合、1 秒あたりの新規リクエスト数 200 件未満が推奨されています。プロキシ有りのVPC では、これらのエラーは発生していません。これは IAM 認証が Lambda 関数とデータベースインスタンスの間で直接使われず、Lambda 関数と RDS Proxy の間で使われているためです(RDS Proxy とデータベースインスタンスの間ではネイティブ認証を使用)。

IAM 認証には利点がありますが、このテストのプロキシ無しの VPC の結果からも明らかなように、秒間 200 件を超える新規接続は推奨できません。ユーザー名とパスワードによるネイティブ認証を使ってデータベースインスタンスに接続し、最大接続数を 16,000 まで 増やすと、このエラーは発生しません(ただし、IAM 認証の利点は失われます)。この負荷テストは、IAM 認証のみを使って RDS Proxy の利点を比較するように設計されています。ネイティブ認証を使用したテストでは、プロキシ無しの VPC の方がはるかに有利であることが示されているため、IAM 認証を必要としない方にはこのアプローチが推奨されています。

CloudWatch コンソールで、ナビゲーションペインの Dashboards を選択して、LoadTestDashboard-{random string} を見つけます(正確な名前は CloudFormation コンソールの Outputs タブにあります)。この CloudWatch ダッシュボードでは、プロキシ有りとプロキシ無しの VPC を比較する形で API Gateway、Lambda、Amazon RDS、RDS Proxy のメトリクスが表示されています。以下のスクリーンショットのダッシュボードは、1,000 ユーザーで 30 分間の負荷テストをしたものです。

これらの指標を自分で調べて違いを確認することをおすすめしますが、いくつかのポイントを説明します(結果は異なる場合があることにご注意ください)。

  • HTTP 500 レスポンスの数は、プロキシ無しでは 1 分あたり約 900 件で、プロキシ有りの場合は 0 件。
  • プロキシ有りの Aurora レプリカの CPU 使用率は、プロキシ無しの場合よりも約 4 倍低い。
  • プロキシ有りのリーダー DB の接続数は、ウォームコネクションプールを使用して、全体を通して一定に保たれている。

また、Lambda の同時接続数が、プロキシ有りの VPC の場合よりも、プロキシ無しの VPC の方がはるかに多いこともわかります。これはリクエストレートが同じでも、プロキシ無しのデータベースのレイテンシーが大きいため、データベースからのレスポンスを待機する関数が増えるためです。ダッシュボードで Lambda Throttles の値が 0 より大きい場合は、Locust の総ユーザー数を減らすか、Lambda 関数の同時実行数の初期値を増やすことを検討してください。詳細については、「クォータの引き上げをリクエストする」をご覧ください。

さらに、Performance Insights を使用して、データベースレイヤーの結果を直接比較できます。これを行うには、Amazon RDS コンソールに移動し、ナビゲーションペインで Performance Insights を選択し、プロキシ有り、およびプロキシ無しのデータベースに対応するデータベースインスタンス識別子を選択します(これらは CloudFormation コンソールの Outputs タブの ProxyAuroraReplica と NoProxyAuroraReplica の 1 と 2 の下にあります)。ここで比較するのに便利な 3 つのメトリックスは、ConnectionsInnodb_rows_read、そして Queries です。これらは Manage metrics を選択することで確認できます。これらの結果は、ご自身で比較してみてください。

Lambda 関数のランタイムが異なれば、結果も異なります。これは、プロキシを使用する以外にも、パフォーマンスを向上させる手順があるということです。また、RPS を変更すると結果も異なり、これはユーザー(ボット)の数を変更することで変更できます。先ほどは 1,000 ユーザーの結果でしたが、次のスクリーンショットでは、3,000 ユーザーで Node.js(上)と Python(下)の両方のランタイムを比較しています。

Locust のダッシュボードで Download Data、次に Download Report の順に選択することで、自分の負荷テスト用に、同様のレポートを作成できます。

RDS Proxy の利点は目に見えて明らかです。単にレイテンシーを減らすだけでなく、テナントが直面するエラーやアクセス拒否されるリクエストの数を減らすことができます。これによる全体的な結論は明らかです。RDS Proxy を使用すると、パフォーマンスを犠牲にすることなく、大規模なテナントの分離を実現できます。

本番環境にて

この投稿で提供しているコードはデモ用であり、本番環境では使用しないでください。もし、このコードを実稼働環境で使用する場合は、次の点に注意してください。

価格設定とクリーンアップ

アイドル状態のリソースに対する支払いを避けるために、テストが終わったらすぐに負荷テストを停止し、負荷テストのスタックを削除してください。150 RPS の負荷テストを 30 分実行した後にすぐテンプレートを削除して約 3.90 USD、4 時間の場合は約 31 USD かかります。負荷テストを行わず、1ヶ月間すべてのリソースを削除せずに放置すると、約 1,293 USD の費用がかかります。これら 3 つの例については、各コンポーネントのコストの内訳を、GitHub リポジトリで確認できます。これらは見積りであり、AWS リージョン、負荷テストの期間やその影響の大きさ、プロキシ有りのVPC のみがデプロイされているのか、当アーキテクチャ全体がデプロイされているのか、その他のいくつかの要因によって変わることに注意してください。

今後の課金を避けるために、スタックを削除してください。もしプロキシ有りの VPC とそのリソースを維持したい場合は、負荷テスト用のスタックのみを削除できます。そのためには、メインスタックページで Update を選択し、Use current template を選択し、Create Load Test Stack パラメーターを False に変更して再デプロイします。この場合 MySQL Aurora クラスターには、負荷テスト用のスタックから生成されたダミーデータが残っているため、データベースを適切に削除する必要があります。Secrets Manager シークレットは削除されます。テンプレート全体を削除すると、アーキテクチャ全体は削除されます。

まとめ

この投稿では、MySQL のパフォーマンスを犠牲にすることなく、大規模なデータベースでテナントの分離を実現する方法を説明しました。プロキシ有りのVPC を用意して、負荷テストを行い、プロキシ無しのVPC と比較しました。この投稿を読むことで、マルチテナントでスケーラブルなデータベースのプロキシソリューションの構築とテスト方法を学び、ソリューションを構成するサービスと、機能に関する知識を深めることができました。詳細については、この投稿のきっかけとなった「AWS Lambda で Amazon RDS Proxy を使用する」をご覧ください。

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