クロスリージョンのVPC間通信をTransit Gatewayでやってみた
同じリージョン内のVPCをTransit Gatewayで接続して通信するということはやったことがあるのですが、クロスリージョンの場合は設定の方法は知っていても実際にやったことは無かったのでやってみました。
やること
東京リージョンと大阪リージョンにVPCを作成してTransit Gateway経由で各リージョンのEC2から対向のリージョンのEC2へpingで疎通できることを確認します。
Transit Gatewayの設定は以下のドキュメントを参考に進めていきます。
構成
構成としては以下の画像の通りとなります。
東京リージョンと大阪リージョンにVPCを作成して各リージョンのTransit Gatewayをピアリング後にルートテーブルを設定して相互に通信できるように設定を行います。
VPCと疎通確認用EC2はCloudFormationで作成してTransit Gatewayはマネジメントコンソールから設定してみたいと思います。
設定
疎通確認用EC2作成
まずは東京リージョンと大阪リージョンにVPCと疎通確認用EC2を作成します。
VPCとEC2の作成は以下のCloudFormationテンプレートで行います。
AWSTemplateFormatVersion: "2010-09-09"
Description: vpc,ec2 stack
Mappings:
# ------------------------------------------------------------#
# Mappings
# ------------------------------------------------------------#
RegionMap:
ap-northeast-3:
VPCCIDR: 10.1.0.0/16
AvailabilityZone: ap-northeast-3a
PrvSubnet1CIDR: 10.1.0.0/24
PrvSubnet2CIDR: 10.1.1.0/24
SecurityGroupCIDR: 10.0.1.0/24
ap-northeast-1:
VPCCIDR: 10.0.0.0/16
AvailabilityZone: ap-northeast-1a
PrvSubnet1CIDR: 10.0.0.0/24
PrvSubnet2CIDR: 10.0.1.0/24
SecurityGroupCIDR: 10.1.1.0/24
Metadata:
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
AWS::CloudFormation::Interface:
ParameterGroups:
Parameters:
- EC2VolumeSize
- EC2VolumeIOPS
- EC2AMI
- EC2InstanceType
Parameters:
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
EC2VolumeSize:
Default: 32
Type: Number
EC2VolumeIOPS:
Default: 3000
Type: Number
EC2AMI:
Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64'
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
EC2InstanceType:
Default: t3.micro
Type: String
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !FindInMap
- RegionMap
- !Ref 'AWS::Region'
- VPCCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: test-vpc
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
PrivateSubnet01:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !FindInMap
- RegionMap
- !Ref 'AWS::Region'
- AvailabilityZone
CidrBlock: !FindInMap
- RegionMap
- !Ref 'AWS::Region'
- PrvSubnet1CIDR
Tags:
- Key: Name
Value: test-private-01
VpcId: !Ref VPC
PrivateSubnet02:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !FindInMap
- RegionMap
- !Ref 'AWS::Region'
- AvailabilityZone
CidrBlock: !FindInMap
- RegionMap
- !Ref 'AWS::Region'
- PrvSubnet2CIDR
Tags:
- Key: Name
Value: test-private-02
VpcId: !Ref VPC
# ------------------------------------------------------------#
# RouteTable
# ------------------------------------------------------------#
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: test-private-rtb
PrivateRtAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable
SubnetId: !Ref PrivateSubnet01
PrivateRtAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable
SubnetId: !Ref PrivateSubnet02
# ------------------------------------------------------------#
# Security Group
# ------------------------------------------------------------#
EC2SG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: for EC2
GroupName: EC2-sg
SecurityGroupEgress:
- CidrIp: 0.0.0.0/0
FromPort: -1
IpProtocol: -1
ToPort: -1
SecurityGroupIngress:
- CidrIp: !FindInMap
- RegionMap
- !Ref 'AWS::Region'
- SecurityGroupCIDR
FromPort: -1
IpProtocol: icmp
ToPort: -1
Tags:
- Key: Name
Value: ec2-sg
VpcId: !Ref VPC
VPCEndpointSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: for VPC Endpoint
GroupName: vpcendpoint-sg
SecurityGroupEgress:
- CidrIp: 0.0.0.0/0
FromPort: -1
IpProtocol: -1
ToPort: -1
SecurityGroupIngress:
- SourceSecurityGroupId: !Ref EC2SG
FromPort: 443
IpProtocol: tcp
ToPort: 443
Tags:
- Key: Name
Value: vpcendpoint-sg
VpcId: !Ref VPC
# ------------------------------------------------------------#
# VPC Endpoint
# ------------------------------------------------------------#
SystemsManagerEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
PrivateDnsEnabled: true
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
VpcId: !Ref VPC
SubnetIds:
- !Ref PrivateSubnet01
SecurityGroupIds:
- !Ref VPCEndpointSG
SystemsManagerMessageEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
PrivateDnsEnabled: true
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
VpcId: !Ref VPC
SubnetIds:
- !Ref PrivateSubnet01
SecurityGroupIds:
- !Ref VPCEndpointSG
# ------------------------------------------------------------#
# IAM
# ------------------------------------------------------------#
EC2IAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
RoleName: !Sub iam-role-ec2-${AWS::Region}
Tags:
- Key: Name
Value: !Sub iam-role-ec2-${AWS::Region}
EC2IAMInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: !Sub iam-instanceprofile-ec2-${AWS::Region}
Roles:
- !Ref EC2IAMRole
# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
EC2:
Type: AWS::EC2::Instance
Properties:
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
DeleteOnTermination: true
Encrypted: true
Iops: !Ref EC2VolumeIOPS
VolumeSize: !Ref EC2VolumeSize
VolumeType: gp3
DisableApiTermination: false
IamInstanceProfile: !Ref EC2IAMInstanceProfile
ImageId: !Ref EC2AMI
InstanceType: !Ref EC2InstanceType
NetworkInterfaces:
- DeleteOnTermination: true
DeviceIndex: 0
GroupSet:
- !Ref EC2SG
SubnetId: !Ref PrivateSubnet02
Tags:
- Key: Name
Value: !Sub test-ec2-${AWS::Region}
上記のCloudFormationテンプレートの110行目~128目でサブネットにルートテーブルを紐づけています。
Transit Gateway作成後にこのルートテーブルに対向のVPCのCIDR宛ルートを追加します。
疎通確認用EC2にはSystems Manager Session Managerで接続するのでSystems ManagerのVPCエンドポイントを作成しています。
CloudFormationテンプレートファイルを作成したら以下のAWS CLIコマンドを実行して東京リージョンと大阪リージョンにデプロイします。
# 東京リージョンへのデプロイ
aws cloudformation create-stack --stack-name スタック名 --template-body file://CloudFormationテンプレートファイル名 --capabilities CAPABILITY_NAMED_IAM --region ap-northeast-1
# 大阪リージョンへのデプロイ
aws cloudformation create-stack --stack-name スタック名 --template-body file://CloudFormationテンプレートファイル名 --capabilities CAPABILITY_NAMED_IAM --region ap-northeast-3
コマンド実行後、しばらくすると各リージョンにEC2が起動していることが確認できます。
起動していることが確認できたら下準備は完了です。
Transit Gateway作成
疎通確認用EC2が作成できたらTransit Gatewayを作成していきます。
東京リージョン
マネジメントコンソールからVPCのダッシュボードに移動後、画面左のメニューから「Transit Gateway」をクリックします。
画面遷移後、「Transit Gatewayを作成」をクリックします。
設定画面が表示されたら「名前タグ」と「説明」にわかりやすいもの (リージョンごとに識別しやすいものを入れるとよいです) を入力して「Amazon 側の自律システム番号 (ASN)」に64512と入力します。
上記で設定した内容以外はデフォルトのまま、画面下にある「Transit Gatewayを作成」をクリックします。
余談ですが、「Transit Gateway を設定」欄にあった設定は以下のような意味になります。
設定名 | 内容 |
---|---|
DNS サポート | Transit Gatewayに接続されたVPCからパブリックIPv4 DNS名を名前解決したときにプライベートIPアドレスに名前解決できるようにする設定です。 例えばVPC AのEC2からVPC BのEC2インスタンスのパブリックIPv4 DNS名を名前解決した際にプライベートIPアドレスに名前解決することが可能になります。 |
セキュリティグループ参照サポート | 別のVPCに紐づいているセキュリティグループをセキュリティグループのインバウンドルールで参照させることが可能になる設定です。 制限などもあるので、以下のブログを参考にしてみてください。 https://dev.classmethod.jp/articles/general-availability-security-group-referencing-aws-transit-gateway/ |
VPN ECMP サポート | VPNトンネル間で等コストマルチパスルーティングを使用する際に必要な設定です。 |
デフォルトルートテーブルの関連付け | Transit Gatewayアタッチメントを作成した際にデフォルトのルートテーブルを自動的に紐づける設定です。 |
デフォルトルートテーブル伝播 | Transit Gatewayアタッチメントを作成した際にデフォルトのルートテーブルにアタッチメントへのルートを伝播する設定です。 |
マルチキャストサポート | マルチキャスト通信を行う際に必要な設定です。 |
「Transit Gatewayを作成」をクリック後、5分くらいで作成が完了します。
Transit Gatewayが作成できたらTransit Gateway アタッチメントを作成します。
画面左のメニューから「Transit Gateway アタッチメント」をクリックして「Transit Gateway アタッチメントを作成」をクリックします。
設定画面が表示されたら「名前タグ」、「Transit Gateway ID」、「VPC ID」、「サブネット ID」を設定します。
「名前タグ」は識別しやすいものを入力してください。
「Transit Gateway ID」は上記の手順で作成したTransit Gatewayを選択してください。
「VPC ID」はCloudFormationで作成したVPCを選択してください。
「サブネット ID」は「test-private-01」を選択してください。
設定をしたら画面下の「Transit Gatewayアタッチメントを作成」をクリックします。
「Transit Gatewayアタッチメントを作成」クリック後、5分程度で状態がAvailableになります。
Transit Gatewayアタッチメントが作成できたらサブネットに紐づいているVPCルートテーブルにTransit Gateway宛のルートを追加します。
画面左のメニューから「ルートテーブル」をクリックし「test-private-rtb」を選択後、「ルート」タブを開いて「ルートを編集」をクリックします。
設定画面に移動したら大阪リージョンのVPC CIDR(10.1.0.0/16)を送信先にしてターゲットでTransit Gatewayを選択して「変更を保存」をクリックします。
大阪リージョン
ここからは大阪リージョンの設定を行います。
手順は東京リージョンのものと同じなので、設定値(ルートテーブルに設定するCIDRなど)に注意しながら設定を進めます。
まずはTransit Gatewayを作成します。
マネジメントコンソールで大阪リージョンを開いたらVPCのダッシュボードに移動後、画面左のメニューから「Transit Gateway」をクリックします。
画面遷移後、「Transit Gatewayを作成」をクリックします。
設定画面が表示されたら「名前タグ」と「説明」にわかりやすいもの (リージョンごとに識別しやすいものを入れるとよいです) を入力して「Amazon 側の自律システム番号 (ASN)」に64513と入力します。
上記で設定した内容以外はデフォルトのまま、画面下にある「Transit Gatewayを作成」をクリックします。
Transit Gatewayが作成できたらTransit Gateway アタッチメントを作成します。
画面左のメニューから「Transit Gateway アタッチメント」をクリックして「Transit Gateway アタッチメントを作成」をクリックします。
設定画面が表示されたら「名前タグ」、「Transit Gateway ID」、「VPC ID」、「サブネット ID」を設定します。
「名前タグ」は識別しやすいものを入力してください。
「Transit Gateway ID」は上記の手順で作成したTransit Gatewayを選択してください。
「VPC ID」はCloudFormationで作成したVPCを選択してください。
「サブネット ID」は「test-private-01」を選択してください。
設定をしたら画面下の「Transit Gatewayアタッチメントを作成」をクリックします。
Transit Gatewayアタッチメントが作成できたらサブネットに紐づいているVPCルートテーブルにTransit Gateway宛のルートを追加します。
画面左のメニューから「ルートテーブル」をクリックし「test-private-rtb」を選択後、「ルート」タブを開いて「ルートを編集」をクリックします。
設定画面に移動したら東京リージョンのVPC CIDR(10.0.0.0/16)を送信先にしてターゲットでTransit Gatewayを選択して「変更を保存」をクリックします。
Transit Gatewayピアリングアタッチメント設定
東京リージョンのTransit Gatewayアタッチメントの画面から「Transit Gatewayアタッチメントを作成」をクリックします。
設定画面が開いたら「名前タグ」、「Transit Gateway ID」、「アタッチメントタイプ」、「リージョン」、「Transit Gateway (アクセプタ)」を設定します。
「名前タグ」は識別しやすいものを入力すれば問題ありません。
「Transit Gateway ID」は東京リージョンのTransit Gateway IDを選択してください。
「アタッチメントタイプ」はPeering Connectionを選択してください。
「リージョン」は大阪リージョンを選択してください。
「Transit Gateway (アクセプタ)」は大阪リージョンで作成したTransit Gateway IDを入力してください。
設定をしたら画面下の「Transit Gatewayアタッチメントを作成」をクリックします。
「Transit Gatewayアタッチメントを作成」をクリックしたら大阪リージョンのTransit Gatewayアタッチメントの画面を開きます。
画面を開くと東京リージョンからのピアリングアタッチメントが表示されるので、「アクション」から「Transit Gatewayアタッチメントを承諾」をクリックします。
承諾が完了したらTransit Gatewayルートテーブルに対向VPC宛のルートを追加します。
東京リージョン、大阪リージョン両方で作業を行います。
Transit Gatewayルートテーブルの画面を開いたら「ルート」タブを開いて「静的ルートを作成」をクリックします。
設定画面が開いたら「CIDR」に対向VPCのCIDRを入力して「アタッチメントを選択」でピアリングアタッチメントを選択してください。
設定を行ったら「静的ルートを作成」をクリックします。
東京リージョンでの設定画面
大阪リージョンでの設定画面
疎通確認
設定が完了したら疎通確認用EC2にSystems Manager Session Managerで接続します。
マネジメントコンソールでEC2インスタンスの画面を開き(東京リージョン、大阪リージョンどちらでも構いません)「接続」をクリックします。
「セッションマネージャー」タブから「接続」をクリックします。
接続ができたらpingコマンドを対向VPCのEC2宛に実行して疎通できていることが確認できれば設定は完了です。(EC2のプライベートIPアドレスはマネジメントコンソールから確認してください)
さいごに
両方のリージョンでのルーティング設定が必要なので、もし疎通に失敗した際はまずTransit Gatewayのルートテーブルの確認から行うとよさそうです。