Techfirm Cloud Architect Blog

テックファーム株式会社クラウドインフラグループのブログ

RDS Proxyを使ってクロスアカウントのプライベート層RDSにアクセスする方法

はじめに

クロスアカウントのRDSに接続する場合、簡単に接続を構築する手法としては下記の様なものがあります。

  • パブリック接続
  • VPCピアリング
  • PrivateLinkとNLB

RDSへのパブリック接続はセキュリティ上好ましくないため、VPCピアリング接続を検討するケースの方が多いと思いますが、通信を行いたいVPCのCIDR重複などネットワークの制約がある場合、ピアリング接続を作成することができません。
そのような場合に、次の接続方式として採用しやすいのが、RDS Proxyを使った接続です。
一方で、3つ目に挙げたPrivateLinkとNLBを使用した接続は、通信上のオーバヘッドが発生する上、RDSのフェールオーバーによるIPアドレスの変更に対し、Lambdaで切り替え処理の実装が必要となり、導入コストの増加が見込まれます。

以上の事から、ピアリング接続ほど設定が簡易ではないものの、比較的導入の難易度が低いRDS Proxyでの接続方式の導入を本稿では推奨し、続いてこのRDS Proxyを使用した接続設定の手順を解説したいと思います。

RDS Proxyを利用するには、AWS Resource Access Manager(AWS RAM)によるアカウント間のリソース共有が必要です。
AWS Organizationsによって組織化されているアカウントを使用している場合は、AWS Organizations内でリソース共有を有効にする必要があります。
設定の詳細はAWS リソースの共有を確認してください。

構築の手順

本稿で紹介する手順は、このようなの流れとなります。

  1. AWS RAMでリソース共有の設定を行う
  2. RDS Proxyを作成する
  3. プロキシエンドポイントを作成する
  4. セキュリティグループを設定する

リソースの共有

RDS Proxyを使ってクロスアカウントのRDS接続を行うには、AWS RAMでリソースを共有しますが、「共有する側」はアプリケーション(RDSに接続したい方)のアカウントで、共有の対象となるのはRDSがあるサブネットです。
また、「共有される側」はRDSのアカウントとなります。
前者をAPP側、後者をRDS側とします。
リソースの共有をするために、APP側のAWS Management Consoleにログインし、Resource Access Managerに移動します。
「リソースの共有」をクリックし、共有したいリソースの情報を入力します。

メンテナンスウィンドウの作成

リソース共有の名前

「リソース共有の名前」には適切な名前を入力します。

リソース

今回はアプリケーション側のサブネットを共有しますので、「リソース - オプション」では「サブネット」を選択してください。
選択後、共有可能なサブネットが一覧で出てきますので、アプリケーションが使用しているサブネットを選択し「次へ」をクリックします。

マネージド型アクセス許可

次の画面では、共有するリソースに従い、「マネージド型アクセス許可」の内容が表示されますので、再度「次へ」をクリックします。

プリンシパル

次の画面では、共有する対象の情報を入力します。
「プリンシパル - オプション」で、共有する対象を選択します。
「すべてのユーザーとの共有を許可」「自分の組織内でのみ共有を許可」から適切なものを選択してください。
「プリンシパルタイプの選択」では、AWSアカウントや組織、OUなどを選択することが可能です。
また、公式には下記の様な記載があり、たとえば組織内のAWSアカウント同士であれば承認手続きが不要となり、設定のみで共有が可能になります。

AWS Organizations共有元のアカウントが組織に属し、組織内の共有が有効になっている場合、共有相手の組織内のすべてのプリンシパルには、招待状を使用せずに自動的にリソース共有へのアクセス権が付与されます。組織のコンテキスト外で共有するアカウントのプリンシパルは、リソース共有に参加するための招待を受け取り、招待を受け入れた後でのみ、共有リソースへのアクセス権が付与されます。

RDS Proxyの作成

AWS RAMの設定が終わったら、RDS側のAWS Management Consoleの、Amazon RDS管理コンソールに移動します。
さらに「プロキシ」に移動し「プロキシの作成」をクリックしてRDS Proxyの作成画面に移動します。

プロキシ設定

プロキシの作成 プロキシ設定

「エンジンファミリー」では、使用するRDSのエンジンにしたがって選択しましょう。

「プロキシ識別子」は、設定画面に記載されている下記の注意書きにある通り、使用中のAWSアカウントのリージョン中でユニークになるよう設定してください。

AWS アカウントが現在の AWS リージョンで所有する、すべてのプロキシ間で一意である必要があります。

「アイドルクライアントの接続タイムアウト」には適切な値を設定します。

プロキシがクライアント接続を閉じるまでの間、接続がアイドル状態を継続できる時間を指定できます。デフォルトは 1,800 秒 (30 分) です。
詳しくはRDS Proxy の管理をご確認ください。

ターゲットグループの設定

プロキシの作成 ターゲットグループの設定

「データベース」では、使用するRDSをプルダウンから選択します。

「接続プールの最大接続数」では、RDSのパラメータグループなどで設定されているmax_connections値に対し、RDS Proxy経由での接続が使用できる割合を1~100で指定します。

プロキシは、これらの接続のすべてを事前に作成するわけではありません。この設定により、ワークロードが必要とするときにプロキシがこれらの接続を確立するための権利を予約します。
詳細はMaxConnectionsPercentを確認してください。

「リーダーエンドポイントを含める」は、選択したデータベースがシングルライター Auroraクラスターである場合に選択することができます。

「追加のターゲットグループの設定」を開くと、「セッション固定フィルタ」、「接続借用タイムアウト」、「初期化クエリ」の設定が出てきます。
「セッション固定フィルタ」は「MariaDB と MySQL」のみで設定でき、また「初期化クエリ」は現在 PostgreSQL ではサポートされていないようです。
詳細はRDS Proxy のスタート方法 を確認してください。
また、RDS Proxyのセッション固定を回避する方法については、RDS Proxy の管理 固定を回避するで詳細な情報が得られます。

認証

プロキシの作成 認証

「認証」ではRDSに接続するための情報を設定します。
RDS Proxyでは、RDSに接続するためのアカウント情報をSecrets Managerのシークレットに登録します。
「Identity and Access Management (IAM) ロール」では、そのシークレットにアクセスするた目に必要な権限を持ったIAMロールを指定します。

「Secrets Manager のシークレット」は、前述のシークレットを指定します。
なければ作成してください。

「クライアント認証タイプ」では、プロキシがクライアントからの接続に使用する認証タイプを選択します。

「IAM 認証」では、プロキシへの接続にIAM認証必須にする場合は「必須」を選択します。

接続

プロキシの作成 接続

「Transport Layer Security が必要」は、プロキシですべてのクライアント接続に対して TLS/SSL を適用する場合に選択します。

「サブネット」は、RDS側の、RDSが属するVPC内のサブネットが全て表示されます。
RDSのサブネットグループに指定されたサブネットを選択して下さい。
また、サブネットは少なくとも2つ選択する必要があります。

「追加の接続設定」で設定する「VPC security group」は、このRDS Proxyに紐づけるセキュリティグループで、新規作成してもあらかじめ作成したものを選択しても問題ありません。
このセキュリティグループは、インバウンドもアウトバウンドも、とくに設定する必要はありません。
このセキュリティグループはのちに使用しますので、セキュリティグループルールIDをメモしておいてください。

「詳細設定」ではログをCloudWatch Logsに出力したければチェックします。

プロキシエンドポイントの作成

AWS RAMで共有したリソースで使用できるエンドポイントを作成します。
AWS Management Consoleで、上記で作成したRDS Proxyの詳細画面に移動し、画面中段あたり右端の「プロキシエンドポイントを作成」をクリックします。

設定

プロキシエンドポイントを作成

「プロキシエンドポイント名」に任意の名前を入力します。
大文字と小文字が区別されないなどの制約があるので注意しましょう。

「ターゲットロール」では、「読み取り/書き込み」「読み取り専用」のどちらかを選択します。
詳細はAmazon RDS Proxy エンドポイントの操作 プロキシエンドポイントの作成を確認してください。

接続

プロキシエンドポイントの作成 接続

「VPC」では、AWS RAMで共有したサブネットが属するVPCがリストに含まれていますので、そちらを選択します。

「サブネット」では、デフォルトでAWS RAMで共有したサブネットが表示されるので、そのままにします。

「VPC security group」では、RDS側のセキュリティグループを選択します。
このセキュリティグループでは、APP側のリソースのセキュリティグループから、RDSのポートに対するインバウンドを許可します。
例えばAPP側のEC2からRDS Proxyへ接続する場合であれば、そのEC2に設定されたセキュリティグループをソースに指定します。

入力が完了したら「プロキシエンドポイントを作成」をクリックし、作成画面を完了します。

セキュリティグループ

本稿で設定する内容で必要なセキュリティグループは3つあります。

  1. RDS Proxyに設定されるセキュリティグループ
  2. プロキシエンドポイントに設定されるセキュリティグループ
  3. RDSに設定されるセキュリティグループ

1は、インバウント・アウトバウンドともに未設定で問題ありません。
2は、前述の通り、APP側のリソースからのインバウントを許可する必要があります。
3のRDSのセキュリティグループでは、RDS Proxyからの接続を許可します。
つまり、ソースを1のセキュリティグループとし、RDSポートへのインバウンドを許可します。

試してみる

では、APP側のリソースから、RDSへ接続してみます。
「プロキシエンドポイントを作成」で作成した、VPC IDがAPP側のIDになっているエンドポイントに対し接続します。
MySQLやPostgresSQLに接続するときに使用するmysqlpsql等のコマンドで接続でき、コマンドのオプションなどはとくに変更する必要はありません。

mysql -h [プロキシ名].endpoint.proxy-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u username -d database -p
psql -h [プロキシ名].endpoint.proxy-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U username -d database

接続時に使用するユーザは、「プロキシの作成」の「認証」で使用したSecrets Managerに登録したユーザを指定してください。
それ以外のユーザで接続すると、下記の様なエラーが出てしまいます。

This RDS proxy has no credentials for the role XXXXX. Check the credentials for this role and try again.

さいごに

RDS Proxyは、各トランザクションの終了時に接続を再利用します。
この再利用によって、「ピン留め」という現象が起こる場合があります。
RDS Proxyを使用する際は、「RDS Proxyのピン留め」についてあらかじめよく調べ、アプリケーションとの相性など事前に充分に検証しましょう。