はじめに
お疲れ様です。矢儀 @yuki_ink です。
re:Invent 2024、楽しんでますか?
マルチモーダル生成AIモデル「Amazon Nova」の発表など、今年もアツいですね。
そんなラインナップの中では地味かもですが、個人的には以下2つのアップデートが刺さりました。
① AWS PrivateLinkでNLBを介さずにVPC内リソースにアクセスできるようになった!!!
② AWS PrivateLink がクロスリージョン接続をサポート!!!
ということは・・・
AWS PrivateLinkで「NLBを介さずに」かつ「クロスリージョンで」、VPC内リソースにアクセスできるのでは???
イメージはこんな感じ。
やってみましょう!!
先に結論
駄目でした!!!
今時点での結論は以下のようです。
- 同一リージョン内では、NLBを介さずにVPC内リソースにアクセスできる
- NLBまたはGWLBを使用するエンドポイントサービスについては、クロスリージョンで接続可能
同一リージョン内では、NLBを介さずにVPC内リソースにアクセスできる
【参考】
NLBの代わりに(?)、Resource gatewayとResource configurationを設定する必要があります。
これらのリソースはVPC Latticeの機能のようですが、そのVPC Latticeは、現状、サービス単体ではクロスリージョン対応していません。
VPCピアリングやTransit Gatewayなどを使って繋ぐか、間にNLBなどを挟むかしないと、クロスリージョン通信はできません。
クロスリージョンおよびオンプレミスの通信パターンについては、現在、クロスリージョン VPC ピアリング、AWS Transit Gateway、AWS Direct Connect、または AWS Cloud WAN などの AWS グローバル接続サービスを利用できます。リージョン間の接続パターンの詳細については、このブログをご覧ください。
(出典)Amazon VPC Lattice のよくある質問
この時点で、ああ、駄目そう・・・という雰囲気が漂ってきますw
AWS PrivateLinkとVPC Latticeの関係性はこちらの素晴らしい記事をご参照ください。
NLBまたはGWLBを使用するエンドポイントサービスについては、クロスリージョンで接続可能
【参考】
のんピさんのまとめが分かりやすかったです。
- PrivateLink ReadyパートナーのサービスやNLBとGWLBを使用するエンドポイントサービスについてクロスリージョンで接続可能
- エンドポイントサービスが公開されているリージョン名を指定する必要がある
- AWSのサービスに対するGateway型VPCエンドポイント、Interface型VPCエンドポイント経由でクロスリージョンで操作することはできない
- 東京リージョンのS3のVPCエンドポイントを介して、大阪リージョンのS3バケットの操作を行うことはできない
- VPCエンドポイントサービス側でサポートするリージョンをサービスリージョンとして指定する
- 複数指定可能
- 追加課金要素は以下
- Interface型VPCエンドポイント所有者 : 追加で通常のクロスリージョンのデータ転送料金がかかる
- VPCエンドポイントサービスの所有者 : アクティブなリモートリージョンごとに固定の時間料金がかかる
- クロスリージョンをサポートするVPCエンドポイントサービスはNLBが複数AZでデプロイされている必要がある
【供養】やってみた
この結論に至るまでに、ちょっと環境を触ってみたので供養します。
目指したのは最初のイメージ図。
事前準備として、東京リージョンとバージニア北部リージョンで、VPC、サブネット、EC2などのリソースを作成します。
CloudFormationでガサっと作成しました。
CloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template to create a private subnet, Security Group, VPC Endpoints, and an Amazon Linux instance with SSM role.
Parameters:
AmazonLinuxAMI:
Description: AMI ID for the Amazon Linux instance
Type: String
Default: ami-0abcdef1234567890 # Replace with a commonly used default value or leave as is for user input.
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "MyVPC-${AWS::Region}"
PrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select
- 0
- !GetAZs ''
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub "MyPrivateSubnet-${AWS::Region}"
RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "MyPrivateRouteTable-${AWS::Region}"
RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet
RouteTableId: !Ref RouteTable
VpcSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow all traffic within the VPC
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: -1 # All protocols
CidrIp: 10.0.0.0/16 # Allow all traffic from the VPC CIDR
SecurityGroupEgress:
- IpProtocol: -1 # All protocols
CidrIp: 0.0.0.0/0 # Allow all outbound traffic
Tags:
- Key: Name
Value: !Sub "MyVpcSecurityGroup-${AWS::Region}"
VPCEndpointSSM:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssm"
SubnetIds:
- !Ref PrivateSubnet
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref VpcSecurityGroup
VPCEndpointEC2Messages:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub "com.amazonaws.${AWS::Region}.ec2messages"
SubnetIds:
- !Ref PrivateSubnet
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref VpcSecurityGroup
VPCEndpointSSMMessages:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssmmessages"
SubnetIds:
- !Ref PrivateSubnet
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref VpcSecurityGroup
SSMRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "AmazonSSMManagedInstanceCoreRole-${AWS::Region}"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Tags:
- Key: Name
Value: !Sub "AmazonSSMManagedInstanceCoreRole-${AWS::Region}"
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: !Sub "AmazonSSMManagedInstanceProfile-${AWS::Region}"
Roles:
- !Ref SSMRole
Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: !Ref AmazonLinuxAMI
SubnetId: !Ref PrivateSubnet
SecurityGroupIds:
- !Ref VpcSecurityGroup
IamInstanceProfile: !Ref InstanceProfile
Tags:
- Key: Name
Value: !Sub "MyAmazonLinuxInstance-${AWS::Region}"
Outputs:
VpcId:
Description: VPC ID
Value: !Ref VPC
PrivateSubnetId:
Description: Private Subnet ID
Value: !Ref PrivateSubnet
SecurityGroupId:
Description: Security Group ID
Value: !Ref VpcSecurityGroup
VPCEndpointSSMId:
Description: VPC Endpoint ID for SSM
Value: !Ref VPCEndpointSSM
VPCEndpointEC2MessagesId:
Description: VPC Endpoint ID for EC2 Messages
Value: !Ref VPCEndpointEC2Messages
VPCEndpointSSMMessagesId:
Description: VPC Endpoint ID for SSM Messages
Value: !Ref VPCEndpointSSMMessages
InstanceId:
Description: Amazon Linux Instance ID
Value: !Ref Instance
CloudFormation実行時、AmazonLinuxAMI
パラメータで、EC2に利用するAMIを選択するのがミソ。
テンプレート自体は各リージョンで同じものを使えます。
別にAmazon Linuxじゃなくてもいいんですが、Amazon LinuxにはSSMエージェントがデフォルトで入っているので便利!
続いて、接続先リージョン(今回はバージニア北部リージョン)でResource gatewayとResource configurationを設定します。
先ほども触れた記事を参考にさせていただきました。
マネージメントコンソールからVPCの画面に行き、PrivateLink and Lattice
> Resource gateways
を選択し Create resource gateway
をクリック。
設定画面に遷移するので、以下のように設定。
VPC、サブネット、セキュリティグループは、事前準備で作成したものを選択します。
続いて、VPC画面の PrivateLink and Lattice
> Resource configurations
を選択し Create resource configuration
を押します。
設定画面に遷移するので、以下のように設定。
Resource gateway
は先ほど作成したものを選択します。
IPアドレスは、バージニア北部リージョンに作成したEC2のプライベートIPアドレスを指定しました。
ここまで来たら、あとは東京リージョン側でVPCエンドポイントを作ればヨシ!
・・・と思ったのですが、東京リージョンの設定画面上に、先ほどバージニア北部リージョンで設定したResouce confugurationが表示されることはなく😅
ここまで来て断念しました。
終わりに
PrivateLinkで他リージョンのVPC内リソースに接続したい場合は、今のところは大人しくNLBを間に挟むか、リージョン間のVPCピアリング(Inter-Region VPC Peering)など別の切り口を考えるかする必要があるという結論でした。
PrivateLinkに関する2つのアップデートについて、字面だけ見て、「これ組み合わせたらいけるんじゃね??」というノリで、勢いで検証に着手しましたが、早々に断念しましたw
「手を動かしてみないと分からないところもある」ということを実感できた点では、良い経験になりました。
まだまだ始まったばかりのre:Invent!引き続き盛り上がっていきましょう!