こんにちは、SCSKでAWSの内製化支援『テクニカルエスコートサービス』を担当している貝塚です。
ある案件で、PrivateLink経由でRDSエンドポイントに接続したいという要件がありました。
RDSエンドポイントのIPアドレスは、RDSのフェイルオーバーなどいくつかの条件で変化してしまう可能性があるため、IPアドレスではなくDNS名で接続することが推奨されます。(以下記事参照)
PrivateLinkはNetwork Load Balancerを使用して実装しますので、接続先(ターゲット)はIPアドレスで指定する必要があります。そのため、フェイルオーバーなどによりRDSのIPアドレスが変わると、PrivateLink経由での接続ができなくなってしまいます。
この問題に対する対応の一例として、これまでは、RDSの発行するフェイルオーバーイベントを拾って、LambdaでNLBのターゲットを書き換えるという対応が取られてきました。
re:Invent 2024でPrivateLinkの新機能が発表!
AWSが配信しているAWS Blackbelt Online Seminar re:Invent 2024 アップデート速報より引用します。
AWS PrivateLinkを介したVPCリソースへのアクセスが可能に
• AWS PrivateLinkを利⽤してVPC内の様々なリソースにアクセス可能に
• 従来はNetwork Load BalancerやGateway Load Balancerを使⽤する場合にのみ利⽤できた
• 今回のアップデートによりAWS Resource Access Managerを利⽤することで任意のVPC内リソースを共有できるようになった
AWSの別の記事によると、
Now, customers can share any VPC resource using AWS Resource Access Manager (AWS RAM). This resource can be an AWS-native resource such as an RDS database, a domain name, or an IP address in another VPC or on-premises environment.
とあります。
つまりは、エンドポイントのDNS名でRDSに接続可能で、NLBの要らないPrivateLinkと考えてよさそうです。
まさに担当案件の悩みを解消する新機能ということで、早速使用してみました。
検証構成
検証構成は以下の通りとしました。
RDSを共有する側のアカウントをアカウントA、RDSを利用する側のアカウントをアカウントBとすると、設定手順は以下の通りとなります。
① アカウントAでResource Gatewayを作成する
② Resource Gatewayに関連付ける形でResource Configurationを作成。RDSのDNS名やポート番号などを指定する
③ Resource Access ManagerでResource ConfigurationをアカウントBに共有する
④ アカウントBでResource Endpointを作成する
① アカウントAでResource Gatewayを作成する
VPCメニューからResource gatewaysを選択し、Create resource gatewayをクリックします。
Resource gateway name, IPアドレスタイプ, 対象のVPCとサブネット, 適用するセキュリティグループを指定してResource Gatewayを作成します。
ここで指定したサブネットからIPアドレスが割り当てられ、共有するリソースへアクセスするときのソースIPになります。少なくともマネジメントコンソールからは、指定できるのはサブネットまででIPアドレスを指定することはできないようです。
② Resource Gatewayに関連付ける形でResource Configurationを作成。RDSのDNS名やポート番号などを指定する
作成されたResource Gatewayの詳細画面からCreate resource configurationを押してResource Configurationを作成します。
単独のDNS名を指定したい場合はConfiguration typeにResourceを指定すればよいようなのでそのようにします。
TypeはSingleを指定します。(他の選択肢、ChildとARNの使い方については後日記事にする予定です)
Resource typeはDNS resourceを選択し、ドメイン名にRDSエンドポイントのFQDNを入力します。
今回、SQL Serverと接続したいので、Port rangesは以下の通り1433のみとしました。
Association settingsはAllowとします。今回はどちらを選んでも関係ないはずです。
Share resource configurationで、Resource Access Managerの設定を指定できますが、今回は、この後Resource Access Managerからリソース共有を設定するので、ここでは空欄にしておきます。
アクセスログの出力先を指定し、Resource Configurationを作成します。
③ Resource Access ManagerでResource ConfigurationをアカウントBに共有する
Resource Access Managerで、自分が共有:リソースの共有から、「リソース共有を作成」をクリックし、リソース共有を作成します。
リソースの種類はVPC Lattice Resource Configurationsです。
共有権限を与えるプリンシパルとしてアカウントBのアカウントIDを指定し、共有を作成します。
④ アカウントBでResource Endpointを作成する
アカウントBでリソース共有を承認後、VPCメニューのエンドポイントを選択し、エンドポイントを作成します。
タイプはリソースを選択します。リソース設定のところに共有されたリソースが表示されるはずですのでそれを選択します。
エンドポイントを作成するVPCとサブネットを選択します。Resource Configurationの作成と同様、(マネージメントコンソールからは)サブネットは選択できてもIPアドレスまでは指定できないようです。
セキュリティグループを選択し、エンドポイントを作成します。
作成されたエンドポイントの「関連付け」タブに、エンドポイントのDNS名が記載されているので確認します。(なぜこんな分かりづらいところに……)
接続確認
アカウントBのEC2から、上で調べたエンドポイントのDNS名にアクセスすると、無事、SQL Serverに接続することができました!
PrivateLinkに期待されている通り、相互に相手のIPを意識することなく接続できています。
なお、CloudWatch Logsを確認すると、以下のようなシンプルなログが出力されていました。
sourceIpPortに、接続に使用したEC2のIP
destinationIpPortに、リソースエンドポイントのIP
gatewayIpPortに、リソースゲートウェイを作成したサブネットのIP
resourceIpPortに、RDSのIP
が表示されていることが分かります。
リソースを共有する側に、このようなログという形でアクセス元のIP情報が残るのは、NLBを使用したPrivateLinkとの違いですね。
まとめ
Resource Endpointを使用することで、RDSのエンドポイント(DNS名)にPrivateLink経由で接続できることが分かりました。
今回、RDSをMulti-AZ構成にしなかったため、FQDNが複数のIPを返してくるときの動作や、RDSエンドポイントのIPが変わったときの動作を確認することができませんでした。
また、VPC Latticeの新機能との組み合わせにより、柔軟なネットワーク接続が可能になっているようです。
今後、これらのことも記事にしていきたいと考えています。