AWS Transit GatewayをCloudFormationで作成する[リージョン内・リージョン間]
TransitGatewayの作成
こんにちわ!
DevelopersIO BASECAMP一期参加の加藤です。
当記事はAdvanced Networking - Specialty試験取得の一環で、理解が曖昧な点を検証しつつ下書き状態にしていたもので、1月半ほど経過して再着手し書き終えたものです。
一期が終了してから、暫く日にちも経っておりますが、運営の皆様にこうしてアウトプットの場を残していただけている為、着手した場所で公開させていただく事といたしました。
2023年5月現在 CloudFormationでのTransitGatewayのお手本がそれほど豊富でない為、TGW RouteTableの設定など私のようにはまってしまう方も少なくないかと思います。当記事の例中に理解の助けになる部分があれば幸いです。
TransitGatewayとは
Transit Gatewayは、仮想プライベートクラウド (VPC) とオンプレミスネットワークを相互接続するために使用できるネットワークの中継ハブです。
TransitGatewayについての詳しくは公式ドキュメントを参照ください。
前置き
今回は、
・動的な伝播の設定
・アカウント跨ぎ
については踏み込めておりません。
①同一リージョン内の別VPC間
以下のブログでお作りになっているものを、周辺のリソースを省略せずに作ってみます。
同一リージョン内の2VPC間で、それぞれプライベート上に立てたEC2同士でPingをTransitGatewayを経由して送り疎通を確認します。
構成図
テンプレート
※元の解説と重複になる為 説明は省略いたします。
sample.yml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
# for VPC1
VPC1CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.1.0.0/16
VPC1PrivateSubnetForEC2CidrBlock: # VPC1のEC2を配置するサブネットのCIDRブロック
Type: String
Default: 10.1.0.0/24
VPC1PrivateSubnetForTransitGatewayAttachmentCidrBlock: # VPC1のTransittGatewayをアタッチするサブネットのCIDRブロック
Type: String
Default: 10.1.1.0/28
# for VPC2
VPC2CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.2.0.0/16
VPC2PrivateSubnetForEC2CidrBlock: # VPC2のEC2を配置するサブネットのCIDRブロック
Type: String
Default: 10.2.0.0/24
VPC2PrivateSubnetForTransitGatewayAttachmentCidrBlock: # VPC1のTransitGatewayをアタッチするサブネットのCIDRブロック
Type: String
Default: 10.2.1.0/28
ImageId: # EC2のImageId(今回は共通)
Type: String
Default: ami-079a2a9ac6ed876fc
InstanceType: # EC2のInstanceType(今回は共通)
Type: String
Default: t2.micro
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: enable
DefaultRouteTablePropagation: enable
VpnEcmpSupport: enable
DnsSupport: enable
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgateway
# for VPC1
VPC1TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC1PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc1
# for VPC2
VPC2TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC2PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref VPC2
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc2
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
# for VPC1
VPC1:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPC1CidrBlock
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-vpc1
# for VPC2
VPC2:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPC2CidrBlock
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-vpc2
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
# for VPC1
VPC1PrivateSubnetForEC2:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC1PrivateSubnetForEC2CidrBlock
VpcId: !Ref VPC1
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc1forec2
VPC1PrivateSubnetForTransitGatewayAttachment:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC1PrivateSubnetForTransitGatewayAttachmentCidrBlock
VpcId: !Ref VPC1
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc1forec2transitgatewayattachment
# for VPC2
VPC2PrivateSubnetForEC2:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC2PrivateSubnetForEC2CidrBlock
VpcId: !Ref VPC2
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc2forec2
VPC2PrivateSubnetForTransitGatewayAttachment:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC2PrivateSubnetForTransitGatewayAttachmentCidrBlock
VpcId: !Ref VPC2
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc2forec2transitgatewayattachment
# ------------------------------------------------------------#
# VPCEndpoint
# ------------------------------------------------------------#
# for VPC1
VPC1VPCEndpointSSM:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC1VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
SubnetIds:
- !Ref VPC1PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC1
VPC1VPCEndpointSSMMessages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC1VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
SubnetIds:
- !Ref VPC1PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC1
VPC1VPCEndpointEC2Messages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC1VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
SubnetIds:
- !Ref VPC1PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC1
VPC1VPCEndpointS3:
Type: AWS::EC2::VPCEndpoint
Properties:
RouteTableIds:
- !Ref VPC1PrivateSubnetForEC2RouteTable
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
VpcEndpointType: Gateway
VpcId: !Ref VPC1
# for VPC2
VPC2VPCEndpointSSM:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC2VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
SubnetIds:
- !Ref VPC2PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC2
VPC2VPCEndpointSSMMessages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC2VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
SubnetIds:
- !Ref VPC2PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC2
VPC2VPCEndpointEC2Messages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC2VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
SubnetIds:
- !Ref VPC2PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC2
VPC2VPCEndpointS3:
Type: AWS::EC2::VPCEndpoint
Properties:
RouteTableIds:
- !Ref VPC2PrivateSubnetForEC2RouteTable
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
VpcEndpointType: Gateway
VpcId: !Ref VPC2
# ------------------------------------------------------------#
# RouteTable
# ------------------------------------------------------------#
# for VPC1
# PrivateSubnetForEC2
VPC1PrivateSubnetForEC2RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-routetable-vpc1privatesubnetforec2
VPC1PrivateSubnetForEC2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref VPC1PrivateSubnetForEC2
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
VPC1TransitGatewayRoute:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref VPC2CidrBlock
TransitGatewayId: !Ref TransitGateway
# for VPC2
# PrivateSubnetForEC2
VPC2PrivateSubnetForEC2RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC2
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-routetable--vpc2privatesubnetforec2
VPC2PrivateSubnetForEC2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref VPC2PrivateSubnetForEC2
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
VPC2TransitGatewayRoute:
Type: AWS::EC2::Route
DependsOn: VPC2TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref VPC1CidrBlock
TransitGatewayId: !Ref TransitGateway
# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
# for VPC1
VPC1EC2:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref EC2InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref VPC1PrivateSubnetForEC2
GroupSet:
- !Ref VPC1EC2SecurityGroup
# for VPC2
VPC2EC2:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref EC2InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref VPC2PrivateSubnetForEC2
GroupSet:
- !Ref VPC2EC2SecurityGroup
# ------------------------------------------------------------#
# IAM
# ------------------------------------------------------------#
# Role
EC2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- ec2.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
# InstanceProfile
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref EC2Role
# ------------------------------------------------------------#
# SecurityGroup
# ------------------------------------------------------------#
# for VPC1
# SecurityGroup
VPC1VPCEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VPC1
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc1
GroupDescription: for VPCE
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc1
# Ingress
VPC1VPCEndpointSecurityGroupIngressEC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: 443
ToPort: 443
IpProtocol: tcp
SourceSecurityGroupId: !Ref VPC1EC2SecurityGroup
GroupId: !GetAtt VPC1VPCEndpointSecurityGroup.GroupId
# SecurityGroup
VPC1EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: VPC1EC2SecurityGroup
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc1ec2
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc1ec2
# Ingress
VPC1EC2SecurityGroupIngressforPing:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC2CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
# for VPC2
# SecurityGroup
VPC2VPCEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VPC2
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc2
GroupDescription: for VPCE
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc2
# Ingress
VPC2VPCEndpointSecurityGroupIngressEC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: 443
ToPort: 443
IpProtocol: tcp
SourceSecurityGroupId: !Ref VPC2EC2SecurityGroup
GroupId: !GetAtt VPC2VPCEndpointSecurityGroup.GroupId
# SecurityGroup
VPC2EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: VPC2EC2SecurityGroup
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc2ec2
VpcId: !Ref VPC2
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc2ec2
# Ingress
VPC2EC2SecurityGroupIngressforPing:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC1CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
コンソールを確認
コンソールから結果を確認してみます。
畳んでいます
TransitGateway(VPC)コンソール
TransitGateway
TransitGatewayアタッチメント
TransitGatewayルートテーブル
-
関連付け
-
アタッチメント
-
ルート
EC2間でPingを実行
それぞれのインスタンスからPingを実行してみます。
VPC1→VPC2
VPC2→VPC1
無事疎通確認が出来ました。
②Inter-Region Peering
続いて、東京リージョンとバージニア北部リージョン間のEC2の疎通を確認してみます。
こちらのブログでのコンソール操作を参考にさせていただきました。
各1VPCでも良い所ですが、今回は①の環境をそれぞれのリージョンで作成し4つのEC2間で疎通を図ります。
構成図
テンプレート
1stRegion.yml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
# for VPC1
VPC1CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.1.0.0/16
VPC1PrivateSubnetForEC2CidrBlock: # VPC1のEC2を配置するサブネットのCIDRブロック
Type: String
Default: 10.1.0.0/24
VPC1PrivateSubnetForTransitGatewayAttachmentCidrBlock: # VPC1のTransittGatewayをアタッチするサブネットのCIDRブロック
Type: String
Default: 10.1.1.0/28
# for VPC2
VPC2CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.2.0.0/16
VPC2PrivateSubnetForEC2CidrBlock: # VPC2のEC2を配置するサブネットのCIDRブロック
Type: String
Default: 10.2.0.0/24
VPC2PrivateSubnetForTransitGatewayAttachmentCidrBlock: # VPC1のTransitGatewayをアタッチするサブネットのCIDRブロック
Type: String
Default: 10.2.1.0/28
# for Both EC2
ImageId: # EC2のImageId(今回は共通)
Type: String
Default: ami-079a2a9ac6ed876fc
InstanceType: # EC2のInstanceType(今回は共通)
Type: String
Default: t2.micro
# for 2ndRegion
# for VPC1
2ndRegionVPC1CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.3.0.0/16
# for VPC2
2ndRegionVPC2CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.4.0.0/16
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: enable
DefaultRouteTablePropagation: enable
VpnEcmpSupport: enable
DnsSupport: enable
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgateway
# for VPC1
VPC1TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC1PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc1
# for VPC2
VPC2TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC2PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref VPC2
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc2
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
# for VPC1
VPC1:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPC1CidrBlock
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-vpc1
# for VPC2
VPC2:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPC2CidrBlock
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-vpc2
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
# for VPC1
VPC1PrivateSubnetForEC2:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC1PrivateSubnetForEC2CidrBlock
VpcId: !Ref VPC1
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc1forec2
VPC1PrivateSubnetForTransitGatewayAttachment:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC1PrivateSubnetForTransitGatewayAttachmentCidrBlock
VpcId: !Ref VPC1
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc1forec2transitgatewayattachment
# for VPC2
VPC2PrivateSubnetForEC2:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC2PrivateSubnetForEC2CidrBlock
VpcId: !Ref VPC2
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc2forec2
VPC2PrivateSubnetForTransitGatewayAttachment:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC2PrivateSubnetForTransitGatewayAttachmentCidrBlock
VpcId: !Ref VPC2
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc2forec2transitgatewayattachment
# ------------------------------------------------------------#
# VPCEndpoint
# ------------------------------------------------------------#
# for VPC1
VPC1VPCEndpointSSM:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC1VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
SubnetIds:
- !Ref VPC1PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC1
VPC1VPCEndpointSSMMessages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC1VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
SubnetIds:
- !Ref VPC1PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC1
VPC1VPCEndpointEC2Messages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC1VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
SubnetIds:
- !Ref VPC1PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC1
VPC1VPCEndpointS3:
Type: AWS::EC2::VPCEndpoint
Properties:
RouteTableIds:
- !Ref VPC1PrivateSubnetForEC2RouteTable
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
VpcEndpointType: Gateway
VpcId: !Ref VPC1
# for VPC2
VPC2VPCEndpointSSM:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC2VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
SubnetIds:
- !Ref VPC2PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC2
VPC2VPCEndpointSSMMessages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC2VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
SubnetIds:
- !Ref VPC2PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC2
VPC2VPCEndpointEC2Messages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC2VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
SubnetIds:
- !Ref VPC2PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC2
VPC2VPCEndpointS3:
Type: AWS::EC2::VPCEndpoint
Properties:
RouteTableIds:
- !Ref VPC2PrivateSubnetForEC2RouteTable
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
VpcEndpointType: Gateway
VpcId: !Ref VPC2
# ------------------------------------------------------------#
# RouteTable
# ------------------------------------------------------------#
# for VPC1
# PrivateSubnetForEC2
VPC1PrivateSubnetForEC2RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-routetable-vpc1privatesubnetforec2
VPC1PrivateSubnetForEC2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref VPC1PrivateSubnetForEC2
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
VPC1TransitGatewayRoute:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref VPC2CidrBlock
TransitGatewayId: !Ref TransitGateway
VPC1TransitGatewayRoutefor2ndRegionVPC1:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 2ndRegionVPC1CidrBlock
TransitGatewayId: !Ref TransitGateway
VPC1TransitGatewayRoutefor2ndRegionVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 2ndRegionVPC2CidrBlock
TransitGatewayId: !Ref TransitGateway
# for VPC2
# PrivateSubnetForEC2
VPC2PrivateSubnetForEC2RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC2
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-routetable-vpc2privatesubnetforec2
VPC2PrivateSubnetForEC2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref VPC2PrivateSubnetForEC2
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
VPC2TransitGatewayRoute:
Type: AWS::EC2::Route
DependsOn: VPC2TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref VPC1CidrBlock
TransitGatewayId: !Ref TransitGateway
VPC2TransitGatewayRoutefor2ndRegionVPC1:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 2ndRegionVPC1CidrBlock
TransitGatewayId: !Ref TransitGateway
VPC2TransitGatewayRoutefor2ndRegionVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 2ndRegionVPC2CidrBlock
TransitGatewayId: !Ref TransitGateway
# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
# for VPC1
VPC1EC2:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref EC2InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref VPC1PrivateSubnetForEC2
GroupSet:
- !Ref VPC1EC2SecurityGroup
# for VPC2
VPC2EC2:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref EC2InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref VPC2PrivateSubnetForEC2
GroupSet:
- !Ref VPC2EC2SecurityGroup
# ------------------------------------------------------------#
# IAM
# ------------------------------------------------------------#
# Role
EC2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- ec2.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
# InstanceProfile
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref EC2Role
# ------------------------------------------------------------#
# SecurityGroup
# ------------------------------------------------------------#
# for VPC1
# SecurityGroup
VPC1VPCEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VPC1
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc1
GroupDescription: for VPCE
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc1
# Ingress
VPC1VPCEndpointSecurityGroupIngressEC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: 443
ToPort: 443
IpProtocol: tcp
SourceSecurityGroupId: !Ref VPC1EC2SecurityGroup
GroupId: !GetAtt VPC1VPCEndpointSecurityGroup.GroupId
#------------------------------------------------------------#
# SecurityGroup
VPC1EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: VPC1EC2SecurityGroup
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc1ec2
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc1ec2
# Ingress
VPC1EC2SecurityGroupIngressFromSameRegionVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC2CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
VPC1EC2SecurityGroupIngressFrom2ndRegionVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndRegionVPC1CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
VPC1EC2SecurityGroupIngressFrom2ndRegionVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndRegionVPC2CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
#------------------------------------------------------------#
# for VPC2
# SecurityGroup
VPC2VPCEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VPC2
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc2
GroupDescription: for VPCE
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc2
# Ingress
VPC2VPCEndpointSecurityGroupIngressEC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: 443
ToPort: 443
IpProtocol: tcp
SourceSecurityGroupId: !Ref VPC2EC2SecurityGroup
GroupId: !GetAtt VPC2VPCEndpointSecurityGroup.GroupId
#------------------------------------------------------------#
# SecurityGroup
VPC2EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: VPC2EC2SecurityGroup
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc2ec2
VpcId: !Ref VPC2
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc2ec2
# Ingress
VPC2EC2SecurityGroupIngressFromSameRegionVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC1CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
VPC2EC2SecurityGroupIngressFrom2ndRegionVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndRegionVPC1CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
VPC2EC2SecurityGroupIngressFrom2ndRegionVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndRegionVPC2CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
Outputs:
PeerRegion:
Value: !Ref AWS::Region
PeerTransitGatewayId:
Value: !Ref TransitGateway
↓
2ndRegion.yml
※Parameter入力画面では、1stRegion.ymlスタックの同名出力値×2を利用ください。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
# for VPC1
VPC1CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.3.0.0/16
VPC1PrivateSubnetForEC2CidrBlock: # VPC1のEC2を配置するサブネットのCIDRブロック
Type: String
Default: 10.3.0.0/24
VPC1PrivateSubnetForTransitGatewayAttachmentCidrBlock: # VPC1のTransittGatewayをアタッチするサブネットのCIDRブロック
Type: String
Default: 10.3.1.0/28
# for VPC2
VPC2CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.4.0.0/16
VPC2PrivateSubnetForEC2CidrBlock: # VPC2のEC2を配置するサブネットのCIDRブロック
Type: String
Default: 10.4.0.0/24
VPC2PrivateSubnetForTransitGatewayAttachmentCidrBlock: # VPC1のTransitGatewayをアタッチするサブネットのCIDRブロック
Type: String
Default: 10.4.1.0/28
# for Both EC2
ImageId: # EC2のImageId(今回は共通)
Type: String
Default: ami-06e46074ae430fba6
InstanceType: # EC2のInstanceType(今回は共通)
Type: String
Default: t2.micro
# for 1stRegion
# for VPC1
1stRegionVPC1CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.1.0.0/16
# for VPC2
1stRegionVPC2CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.2.0.0/16
PeerRegion: # 1stリージョンのスタックの同名出力値を入力
Type: String
PeerTransitGatewayId: # 1stリージョンのスタックの同名出力値を入力
Type: String
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: enable
DefaultRouteTablePropagation: enable
VpnEcmpSupport: enable
DnsSupport: enable
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgateway
# for VPC1
VPC1TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC1PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc1
# for VPC2
VPC2TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC2PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref VPC2
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc2
TransitGatewayPeeringAttachment:
Type: AWS::EC2::TransitGatewayPeeringAttachment
Properties:
PeerAccountId: !Ref AWS::AccountId
PeerRegion: !Ref PeerRegion
PeerTransitGatewayId: !Ref PeerTransitGatewayId
TransitGatewayId: !Ref TransitGateway
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
# for VPC1
VPC1:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPC1CidrBlock
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-vpc1
# for VPC2
VPC2:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPC2CidrBlock
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-vpc2
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
# for VPC1
VPC1PrivateSubnetForEC2:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC1PrivateSubnetForEC2CidrBlock
VpcId: !Ref VPC1
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc1forec2
VPC1PrivateSubnetForTransitGatewayAttachment:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC1PrivateSubnetForTransitGatewayAttachmentCidrBlock
VpcId: !Ref VPC1
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc1forec2transitgatewayattachment
# for VPC2
VPC2PrivateSubnetForEC2:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC2PrivateSubnetForEC2CidrBlock
VpcId: !Ref VPC2
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc2forec2
VPC2PrivateSubnetForTransitGatewayAttachment:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref VPC2PrivateSubnetForTransitGatewayAttachmentCidrBlock
VpcId: !Ref VPC2
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-subnet-private-vpc2forec2transitgatewayattachment
# ------------------------------------------------------------#
# VPCEndpoint
# ------------------------------------------------------------#
# for VPC1
VPC1VPCEndpointSSM:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC1VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
SubnetIds:
- !Ref VPC1PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC1
VPC1VPCEndpointSSMMessages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC1VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
SubnetIds:
- !Ref VPC1PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC1
VPC1VPCEndpointEC2Messages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC1VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
SubnetIds:
- !Ref VPC1PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC1
VPC1VPCEndpointS3:
Type: AWS::EC2::VPCEndpoint
Properties:
RouteTableIds:
- !Ref VPC1PrivateSubnetForEC2RouteTable
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
VpcEndpointType: Gateway
VpcId: !Ref VPC1
# for VPC2
VPC2VPCEndpointSSM:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC2VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
SubnetIds:
- !Ref VPC2PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC2
VPC2VPCEndpointSSMMessages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC2VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
SubnetIds:
- !Ref VPC2PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC2
VPC2VPCEndpointEC2Messages:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: true
SecurityGroupIds:
- !Ref VPC2VPCEndpointSecurityGroup
ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
SubnetIds:
- !Ref VPC2PrivateSubnetForEC2
VpcEndpointType: Interface
VpcId: !Ref VPC2
VPC2VPCEndpointS3:
Type: AWS::EC2::VPCEndpoint
Properties:
RouteTableIds:
- !Ref VPC2PrivateSubnetForEC2RouteTable
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
VpcEndpointType: Gateway
VpcId: !Ref VPC2
# ------------------------------------------------------------#
# RouteTable
# ------------------------------------------------------------#
# for VPC1
# PrivateSubnetForEC2
VPC1PrivateSubnetForEC2RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-routetable-vpc1privatesubnetforec2
VPC1PrivateSubnetForEC2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref VPC1PrivateSubnetForEC2
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
VPC1TransitGatewayRouteforSameRegionVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref VPC2CidrBlock
TransitGatewayId: !Ref TransitGateway
VPC1TransitGatewayRoutefor1stRegionVPC1:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 1stRegionVPC1CidrBlock
TransitGatewayId: !Ref TransitGateway
VPC1TransitGatewayRoutefor1stRegionVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 1stRegionVPC2CidrBlock
TransitGatewayId: !Ref TransitGateway
# for VPC2
# PrivateSubnetForEC2
VPC2PrivateSubnetForEC2RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC2
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-routetable-vpc2privatesubnetforec2
VPC2PrivateSubnetForEC2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref VPC2PrivateSubnetForEC2
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
VPC2TransitGatewayRouteforSameRegionVPC2:
Type: AWS::EC2::Route
DependsOn: VPC2TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref VPC1CidrBlock
TransitGatewayId: !Ref TransitGateway
VPC2TransitGatewayRoutefor1stRegionVPC1:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 1stRegionVPC1CidrBlock
TransitGatewayId: !Ref TransitGateway
VPC2TransitGatewayRoutefor1stRegionVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 1stRegionVPC2CidrBlock
TransitGatewayId: !Ref TransitGateway
# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
# for VPC1
VPC1EC2:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref EC2InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref VPC1PrivateSubnetForEC2
GroupSet:
- !Ref VPC1EC2SecurityGroup
# for VPC2
VPC2EC2:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref EC2InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref VPC2PrivateSubnetForEC2
GroupSet:
- !Ref VPC2EC2SecurityGroup
# ------------------------------------------------------------#
# IAM
# ------------------------------------------------------------#
# Role
EC2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- ec2.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
# InstanceProfile
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref EC2Role
# ------------------------------------------------------------#
# SecurityGroup
# ------------------------------------------------------------#
# for VPC1
# SecurityGroup
VPC1VPCEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VPC1
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc1
GroupDescription: for VPCE
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc1
# Ingress
VPC1VPCEndpointSecurityGroupIngressEC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: 443
ToPort: 443
IpProtocol: tcp
SourceSecurityGroupId: !Ref VPC1EC2SecurityGroup
GroupId: !GetAtt VPC1VPCEndpointSecurityGroup.GroupId
#------------------------------------------------------------#
# SecurityGroup
VPC1EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: VPC1EC2SecurityGroup
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc1ec2
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc1ec2
# Ingress
VPC1EC2SecurityGroupIngressFromSameRegionVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC2CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
VPC1EC2SecurityGroupIngressFrom1atRegionVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stRegionVPC1CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
VPC1EC2SecurityGroupIngressFrom1stRegionVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stRegionVPC2CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
#------------------------------------------------------------#
# for VPC2
# SecurityGroup
VPC2VPCEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VPC2
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc2
GroupDescription: for VPCE
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpcendpoint-vpc2
# Ingress
VPC2VPCEndpointSecurityGroupIngressEC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: 443
ToPort: 443
IpProtocol: tcp
SourceSecurityGroupId: !Ref VPC2EC2SecurityGroup
GroupId: !GetAtt VPC2VPCEndpointSecurityGroup.GroupId
#------------------------------------------------------------#
# SecurityGroup
VPC2EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: VPC2EC2SecurityGroup
GroupName: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc2ec2
VpcId: !Ref VPC2
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-securitygroup-vpc2ec2
# Ingress
VPC2EC2SecurityGroupIngressFromSameRegionVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC1CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
VPC2EC2SecurityGroupIngressFrom1atRegionVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stRegionVPC1CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
VPC2EC2SecurityGroupIngressFrom1stRegionVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stRegionVPC2CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
Outputs:
TransitGatewayPeeringAttachment:
Value: !Ref TransitGatewayPeeringAttachment
Export:
Name: TransitGatewayPeeringAttachment
↓
コンソールからピアリングの承諾を行う
コンソールからピアリングの承諾を行う
「Transit Gateway アタッチメント」を確認すると、
状態:Pending Acceptanceとなっているリソースが確認できます。
-
us-east-1
-
ap-northeast-1
リクエスタとアクセプタがそれぞれ設定のリージョンになっている事が確認出来ました。
↓
アクセプタリージョンであるap-northeast-1の当該アタッチメントの「アクション」から「TransitGatewayアタッチメントを承諾」をクリックします。
↓
それぞれ、状態:Pendingに変わり、数分待つと
↓
-
us-east-1
-
ap-northeast-1
状態:Availableとなりました!
↓
追加テンプレート
1stRegionTransitRoute.yml
※Parameter入力画面では、AutoCreatedTransitGatewayRouteTableIdには1stRegionに自動作成された無名(※Name:「-」)のTransit Gateway ルートテーブル IDを、TransitGatewayPeeringAttachmentには2ndRegion.ymlスタックの同名出力値を入力ください。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
2ndRegionVPC1CidrBlock:
Type: String
Default: 10.3.0.0/16
2ndRegionVPC2CidrBlock:
Type: String
Default: 10.4.0.0/16
TransitGatewayPeeringAttachment: # 2ndリージョンのスタックの同名出力値を参照
Type: String
AutoCreatedTransitGatewayRouteTableId:
Type: String
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
TransitGatewayRouteFor2ndRegionVPC1:
Type: AWS::EC2::TransitGatewayRoute
Properties:
Blackhole: false
DestinationCidrBlock: !Ref 2ndRegionVPC1CidrBlock
TransitGatewayAttachmentId: !Ref TransitGatewayPeeringAttachment
TransitGatewayRouteTableId: !Ref AutoCreatedTransitGatewayRouteTableId
TransitGatewayRouteFor2ndRegionVPC2:
Type: AWS::EC2::TransitGatewayRoute
Properties:
Blackhole: false
DestinationCidrBlock: !Ref 2ndRegionVPC2CidrBlock
TransitGatewayAttachmentId: !Ref TransitGatewayPeeringAttachment
TransitGatewayRouteTableId: !Ref AutoCreatedTransitGatewayRouteTableId
↓
2ndRegionTransitRoute.yml
※Parameter入力画面では、AutoCreatedTransitGatewayRouteTableIdには2ndRegionに自動作成された無名(※Name:「-」)のTransit Gateway ルートテーブル IDを入力ください。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
1stResionVPC1CidrBlock:
Type: String
Default: 10.1.0.0/16
1stResionVPC2CidrBlock:
Type: String
Default: 10.2.0.0/16
AutoCreatedTransitGatewayRouteTableId:
Type: String
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
TransitGatewayRouteFor1stResionVPC1:
Type: AWS::EC2::TransitGatewayRoute
Properties:
Blackhole: false
DestinationCidrBlock: !Ref 1stResionVPC1CidrBlock
TransitGatewayAttachmentId: !ImportValue TransitGatewayPeeringAttachment
TransitGatewayRouteTableId: !Ref AutoCreatedTransitGatewayRouteTableId
TransitGatewayRouteFor1stResionVPC2:
Type: AWS::EC2::TransitGatewayRoute
Properties:
Blackhole: false
DestinationCidrBlock: !Ref 1stResionVPC2CidrBlock
TransitGatewayAttachmentId: !ImportValue TransitGatewayPeeringAttachment
TransitGatewayRouteTableId: !Ref AutoCreatedTransitGatewayRouteTableId
EC2間でPingを実行
こちらもEC2間で疎通確認をしてみます。
画像はひとつだけですが、全インスタンスで疎通確認が出来ました。
おまけ
ちなみに、当記事を下書きのまま公開出来ていなかったのは、Inter-Regionの例で何故かPingが通らなくて原因探しが必要だったという理由なのですが、あれこれ間違った理解の可能性をひっくり返して探す という事を本日していました。
結果、SecurityGroupIngressで!Refしていた論理IDを一文字間違えていたという凡ミスだった訳なのですが、そのおかげであれこれしている中でTGW Route Analyzerと出会う事ができました。
この機能のおかげで「ここが問題ないって事はまさかSGミスってる..?」となり、解決に至る事ができました。
せっかくなので、簡易ですが使い方の流れをスクショで置いておきます。
TGW Route Analyzerの使い方
TGW Route Analyzerの使い方
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
テンプレートで作成する場合は
以下のように、「TransitGatewayRegistration」は各リージョンでスタック実行をしないとエラーが起こります。
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
TransitGatewayId:
Type: String
Resources:
# ------------------------------------------------------------#
# NetworkManager
# ------------------------------------------------------------#
# GlobalNetwork
GlobalNetwork:
Type: AWS::NetworkManager::GlobalNetwork
Properties:
Description: this is test.
Tags:
- Key: Name
Value: test-globalnetwork
# TransitGatewayRegistration
TransitGatewayRegistration:
Type: AWS::NetworkManager::TransitGatewayRegistration
Properties:
GlobalNetworkId: !Ref GlobalNetwork
TransitGatewayArn: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:transit-gateway/${TransitGatewayId}
Outputs:
GlobalNetworkId:
Value: !Ref GlobalNetwork
↓
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
TransitGatewayId:
Type: String
GlobalNetworkId:
Type: String
Resources:
# ------------------------------------------------------------#
# NetworkManager
# ------------------------------------------------------------#
# TransitGatewayRegistration
TransitGatewayRegistration:
Type: AWS::NetworkManager::TransitGatewayRegistration
Properties:
GlobalNetworkId: !Ref GlobalNetworkId
TransitGatewayArn: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:transit-gateway/${TransitGatewayId}
終わりに
お読みいただき有難うございました。
Discussion