2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GenUの閉域モードを2環境構築して、VPCエンドポイントを集約できるか検証する

2
Posted at

はじめに

GenUの閉域モードは、各種リソースにVPCエンドポイント経由で接続します。オンプレミス端末からは直接VPCエンドポイントにアクセスする処理があり、VPCエンドポイントの名前解決が必要になります。オンプレミスのDNSサーバで該当ドメインに関して、フォワード設定を行いますが、仕組み上、フォワード先がVPCエンドポイントの集約アカウントとなります。今回はGenUの構成を2つ作成し、名前解決の動作を確認しながら、どのような構成が考えられるか検証を行います。

共有リソースVPCのVPCエンドポイントを経由してGenUへ接続する構成は、下記@takeda_h(takeda_h)さんの記事で紹介されています。この記事ではGenUのCDKを改修し、API Gatewayのリソースポリシーに共有リソースVPCのVPCエンドポイントを追加しています。今回はCDKを改修せず、API GatewayのVPCエンドポイントだけを環境ごとに分ける方式を検証しました。

検証環境

VPC CIDR 内容
オンプレミス想定VPC 10.0.0.0/16 EC2(Windows Server)。DNSサーバーの役割を追加し、DNSサーバーを兼用
GenU環境A(アカウントA) 10.1.0.0/16 GenUの閉域モード
GenU環境B(アカウントB) 10.2.0.0/16 GenUの閉域モード

3つのVPCはTransit Gatewayで接続しています。GenUはpackages/cdk/cdk.jsonの下記4項目だけを既定値から変更してデプロイしています。

項目 設定値
closedNetworkMode true
closedNetworkVpcIpv4Cidr 環境Aは10.1.0.0/16、環境Bは10.2.0.0/16
modelRegion ap-northeast-1
modelIds ["jp.amazon.nova-2-lite-v1:0"]

① GenUの閉域モード環境を1つ構築する

GenUを1環境デプロイした基本構成は下記の通りです。

aws01.png

名前解決の転送先と通信の流れは下記の通りです。

fig01.png

水色がオンプレミス側で設定するもの、緑がGenUがデプロイするリソースです。

クライアントPCのDNSサーバーに条件付きフォワーダーを設定し、GenUの利用に必要なDNS名を環境Aのインバウンドエンドポイントへ転送します。名前解決が必要なエンドポイントの一覧は、GenUのドキュメントに記載されています。

EC2のDNSサーバーを自分自身に変更する

今回EC2サーバを確認用クライアント兼DNSサーバとして使用します。EC2にDNSサーバーの役割を追加し、優先DNSサーバーを自分自身(127.0.0.1)に変更します。

ss02.png

EC2はFleet Manager経由で操作しているため、ssm.ap-northeast-1.amazonaws.comとssmmessages.ap-northeast-1.amazonaws.comはオンプレミス想定VPCのDNS(10.0.0.2)へ転送しています。このエンドポイントの名前解決が出来ないとFleet Managerで接続出来なくなります。

ss01.png

DNSサーバーにALBのDNS名の条件付きフォワーダーを設定する

ALBのDNS名はClosedNetworkStackの出力ClosedNetworkWebUrlで確認できます。

ss03.png

DNSマネージャーの条件付きフォワーダーに、ALBのDNS名と環境Aのインバウンドエンドポイントを登録します。

ss05.png

登録後、ALBのDNS名にアクセスするとGenUのサインイン画面が表示されます。

ss06.png

ただし、ALBのDNS名だけではアカウントの作成やユーザ認証時に「A network error has occurred.」と表示されます。CognitoのDNS名を名前解決できていないためです。

ss07.png

DNSサーバーにGenUが利用するサービスの条件付きフォワーダーを設定する

ここからはコマンドでドキュメントの一覧にあるDNS名をまとめて登録します。API GatewayのDNS名はGenerativeAiUseCasesStackの出力ApiEndpointで確認できます。

$resolverA = @("10.1.x.x","10.1.y.y")   # 環境Aのインバウンドエンドポイント

$zones = @(
  "aaaaaaaaaa.execute-api.ap-northeast-1.amazonaws.com",   # API Gateway
  "cognito-idp.ap-northeast-1.amazonaws.com",
  "cognito-identity.ap-northeast-1.amazonaws.com",
  "s3.ap-northeast-1.amazonaws.com",
  "lambda.ap-northeast-1.amazonaws.com",
  "transcribe.ap-northeast-1.amazonaws.com",
  "transcribestreaming.ap-northeast-1.amazonaws.com",
  "polly.ap-northeast-1.amazonaws.com",
  "bedrock-agentcore.ap-northeast-1.amazonaws.com"
)

foreach ($z in $zones) {
  Add-DnsServerConditionalForwarderZone -Name $z -MasterServers $resolverA
}

ss08.png

上記設定後、サインインしてチャットの応答まで表示されることを確認しました。

ss09.png

② GenUの閉域モード環境を2つ構築する

下記にもう一つGenUの環境をデプロイしました。

aws02.png

fig02.png

環境Bを構築し、ALBのDNS名だけを環境Bのインバウンドエンドポイントへ転送します。API GatewayのDNS名とそれ以外のサービス名は、環境Aのインバウンドエンドポイントへ転送します。

$resolverB = @("10.2.x.x","10.2.y.y")   # 環境Bのインバウンドエンドポイント

Add-DnsServerConditionalForwarderZone `
  -Name "internal-closed-close-zzzzzzzzzzzz-zzzzzzzzz.ap-northeast-1.elb.amazonaws.com" `
  -MasterServers $resolverB
Add-DnsServerConditionalForwarderZone `
  -Name "bbbbbbbbbb.execute-api.ap-northeast-1.amazonaws.com" `
  -MasterServers $resolverA

ss10.png

環境BのAPI GatewayのDNS名も環境Aのインバウンドエンドポイントで名前解決でき、環境AのAPI GatewayのVPCエンドポイントのIPアドレスが返ります。

Cognitoへの通信が環境AのVPCエンドポイントを経由することを確認する

環境BのALBのURLにアクセスし、サインインとチャットの応答まで表示されることを確認しました。環境BのCloudTrailには、サインイン時のInitiateAuthが下記のように記録されています。

{
  "eventSource": "cognito-idp.amazonaws.com",
  "eventName": "InitiateAuth",
  "sourceIPAddress": "10.0.x.x",
  "recipientAccountId": "222222222222",
  "vpcEndpointId": "vpce-xxxxxxxxxxxxxxxxx",
  "vpcEndpointAccountId": "111111111111",
  "tlsDetails": {
    "clientProvidedHostHeader": "cognito-idp.ap-northeast-1.amazonaws.com"
  }
}

recipientAccountIdが環境BのアカウントID、vpcEndpointAccountIdが環境AのアカウントIDです。環境AのVPCエンドポイントを経由して、環境BのCognitoのユーザープールにリクエストが届いています。環境BのCognitoのユーザープールにも、作成したユーザーが登録されていました。

ss11.png

チャットの読み上げで実行されるPollyのSynthesizeSpeechも、同じく環境AのVPCエンドポイントを経由して環境Bで記録されました。

API Gatewayへの通信が拒否されることを確認する

一方で、API Gatewayを経由する処理である、チャット履歴の読み込みとファイルの添付は失敗しました。ブラウザの開発者ツールで確認すると、API Gatewayへのリクエストに403が返っています。

ss12.png

GenUのCDKでは、API Gatewayのリソースポリシーが下記のように定義されています(packages/cdk/lib/construct/api.ts)。

policy: vpc
  ? new PolicyDocument({
      statements: [apiGatewayVpcEndpoint!].map(
        (e: InterfaceVpcEndpoint) => {
          return new PolicyStatement({
            effect: Effect.ALLOW,
            principals: [new AnyPrincipal()],
            actions: ['execute-api:Invoke'],
            resources: ['execute-api:/*'],
            conditions: {
              StringEquals: {
                'aws:SourceVpce': e.vpcEndpointId,
              },
            },
          });
        }
      ),
    })
  : undefined,

許可されているのは、その環境自身が作成したAPI GatewayのVPCエンドポイントだけです。環境AのVPCエンドポイントを経由するとaws:SourceVpceが環境AのVPCエンドポイントIDになるため、環境BのAPI Gatewayでは許可されません。

③ API GatewayのVPCエンドポイントを環境ごとに分けて名前解決する

構成は下記の通りです。API GatewayのみアカウントB経由で接続します。

aws03.png

名前解決の転送先と通信の流れは下記の通りです。

fig03.png

環境BのAPI GatewayのDNS名だけ、転送先を環境Bのインバウンドエンドポイントに変更します。

Remove-DnsServerZone -Name "bbbbbbbbbb.execute-api.ap-northeast-1.amazonaws.com" -Force
Add-DnsServerConditionalForwarderZone `
  -Name "bbbbbbbbbb.execute-api.ap-northeast-1.amazonaws.com" `
  -MasterServers $resolverB

変更後は、環境BのAPI GatewayのVPCエンドポイントのIPアドレス(10.2.x.x)が返ります。また、環境Bの画面からファイルを添付し、チャットの応答まで表示されることを確認しました。

ss13.png

署名付きURLの発行は環境BのAPI Gatewayを経由します。アップロード先のS3は、条件付きフォワーダーの設定上、環境AのS3のVPCエンドポイントを経由します。

④ VPCエンドポイントを集約VPCにまとめ、API Gatewayだけ環境ごとに分ける

構成は下記の通りです。基本的な通信を集約VPCのVPCエンドポイント経由としつつ、ALBとAPI Gatewayの通信をGenUアカウント経由とします。

aws04.png

名前解決の転送先と通信の流れは下記の通りです。

fig04.png

ALBとAPI GatewayのDNS名を各GenU環境のインバウンドエンドポイントへ転送し、それ以外のサービス名を1つのVPCのインバウンドエンドポイントへ転送します。今回の検証では、環境Aがこの集約VPCの役割になっています。

DNS名 転送先
ALBのDNS名 各GenU環境のインバウンドエンドポイント
API GatewayのDNS名(<API ID>.execute-api.ap-northeast-1.amazonaws.com) 各GenU環境のインバウンドエンドポイント
cognito-idp、cognito-identity、lambda、polly、s3 集約VPCのインバウンドエンドポイント

おわりに

GenUの閉域モード環境を2つ構築し、API Gateway以外のVPCエンドポイントを1つのVPCにまとめられることを確認しました。Cognito、Lambda、Pollyは、別のアカウントのVPCエンドポイントを経由しても、各環境のリソースにリクエストが届きます。API Gatewayはリソースポリシーで自環境のVPCエンドポイントだけを許可しているため、API GatewayのDNS名を環境ごとのインバウンドエンドポイントへ転送することで、CDKを改修せずに利用できました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?