[CFn]AWS Resource Access ManagerでAWS Transit Gatewayを複数アカウントから共有利用する
アカウント間で共有利用出来るTransitGatewayの作成
こんにちわ!
DevelopersIO BASECAMP一期の加藤です。
前回、以下のような記事を投稿いたしました。
今回はアカウント跨ぎでインスタンス同士の疎通確認まで行ってみたいと思います。
①中間アカウントをオーナーとしてResource Access ManagerでTransit Gatewayを作成し、2つのアカウント(※リソースのリージョンは共通)に作成したアタッチメントと接続
字で伝えようとすると少し長くなりましたが、以下が今回作成するものです。
前回記事で同リージョン内と別リージョン間で4つのインスタンスでの疎通をしましたので、今回は同リージョン内と別アカウント間を試してみます。
構成図
※上図では抜けておりますが、中間のtgwアカウントもap-northeast-1となります。
参考にした記事。
以下の記事を参考にさせていただきました。
序盤に試すものだけであれば以下の記事を見ていただければ、テンプレの良さも一緒に勉強出来ますのでお勧めです。ConditonsやMappingを利用して、複数アカウントで共有にしている所が美しいです。
事前準備
・AWS Organizationsからテスト用のアカウントを2つ作成します。(合計3つのアカウントが存在するように)
※アカウント作成時のメールアドレスにお困りの方はGmailのエイリアスアドレス機能がおすすめです。
例:「hogehoge@gmail.com」を所有→「hogehoge+fuga@gmail.com」「hogehoge+piyo@gmail.com」をエイリアスアドレスとして利用可能
ちなみに今回は、3アカウントを横断して作業する為、私はわかりやすいようにChrome,Safari,Firefoxでそれぞれ閲覧するようにしていました。
手順
※tgwアカウント、アカウントA、アカウントB全ての作業は同一リージョンで行ってください。
※amiがap-northeast-1を想定していますので、別リージョンの場合はそれぞれのスタック作成時に「ImageId」パラメーターの値を変更してください。
tgw用にするアカウントで以下テンプレートを実行。
tgw_account.yml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
AccountAId:
Type: String
AccountBId:
Type: String
#リソース定義
Resources:
# ------------------------------------------------------------#
# RAM
# ------------------------------------------------------------#
ResourceShare:
Type: AWS::RAM::ResourceShare
DependsOn:
- TransitGateway
Properties:
Name: !Sub ${PJPrefix}-${Environment}-ram
ResourceArns:
- !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:transit-gateway/${TransitGateway}
Principals:
- !Ref AccountAId
- !Ref AccountBId
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-ram
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
AmazonSideAsn: 64512 # デフォルト値
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: enable
DefaultRouteTablePropagation: enable
DnsSupport: enable
VpnEcmpSupport: enable
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgateway
Outputs:
TransitGatewayId:
Value: !Ref TransitGateway
↓
tgw用アカウントのAWS Resource Access Manager(RAM)コンソールへ移動してみると、「自分が共有:リソース共有」に以下のように表示されている事が見て取れます。
↓
アカウントA、アカウントBでもそれぞれ、RAMコンソールに移動し以下作業を実行。
RAM作業
「自分と共有:リソースの共有」へ移動し、以下の手順でtgwアカウントからのリソース共有の承認を行います。
↓
↓
↓
↓
「自分と共有:リソースの共有」の中に先ほど確認出来たtgwリソースがなくなり、一つ下のタブの「自分と共有:共有リソース」に同リソースが確認出来るようになります。
↓
これが確認出来ていれば承認は正常に完了しています。
↓
A/Bのアカウントで承認が完了すると、tgwアカウントで以下のように「共有プリンシパル」のステータスが「関連付け済み」になっている事が確認出来ます。
↓
アカウントAで以下テンプレートを実行します。
tgw_account.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 2ndAccount
# for VPC1
2ndAccountVPC1CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.3.0.0/16
# for VPC2
2ndAccountVPC2CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.4.0.0/16
# tgw_account.ymlの同名出力値を入力
TransitGatewayId:
Type: String
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
# for VPC1
VPC1TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC1PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGatewayId
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 TransitGatewayId
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 TransitGatewayId
VPC1TransitGatewayRoutefor2ndAccountVPC1:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 2ndAccountVPC1CidrBlock
TransitGatewayId: !Ref TransitGatewayId
VPC1TransitGatewayRoutefor2ndAccountVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 2ndAccountVPC2CidrBlock
TransitGatewayId: !Ref TransitGatewayId
# 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 TransitGatewayId
VPC2TransitGatewayRoutefor2ndAccountVPC1:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 2ndAccountVPC1CidrBlock
TransitGatewayId: !Ref TransitGatewayId
VPC2TransitGatewayRoutefor2ndAccountVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 2ndAccountVPC2CidrBlock
TransitGatewayId: !Ref TransitGatewayId
# ------------------------------------------------------------#
# 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
VPC1EC2SecurityGroupIngressFromSameAccountVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC2CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
VPC1EC2SecurityGroupIngressFrom2ndAccountVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndAccountVPC1CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
VPC1EC2SecurityGroupIngressFrom2ndAccountVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndAccountVPC2CidrBlock
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
VPC2EC2SecurityGroupIngressFromSameAccountVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC1CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
VPC2EC2SecurityGroupIngressFrom2ndAccountVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndAccountVPC1CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
VPC2EC2SecurityGroupIngressFrom2ndAccountVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndAccountVPC2CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
↓
アカウントBで以下テンプレートを実行します。
tgw_account.yml
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-079a2a9ac6ed876fc
InstanceType: # EC2のInstanceType(今回は共通)
Type: String
Default: t2.micro
# for 1stAccount
# for VPC1
1stAccountVPC1CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.1.0.0/16
# for VPC2
1stAccountVPC2CidrBlock: # VPC1のCIDRブロック
Type: String
Default: 10.2.0.0/16
TransitGatewayId: # 1stリージョンのスタックの同名出力値を入力
Type: String
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
# for VPC1
VPC1TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC1PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGatewayId
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 TransitGatewayId
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
VPC1TransitGatewayRouteforSameAccountVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref VPC2CidrBlock
TransitGatewayId: !Ref TransitGatewayId
VPC1TransitGatewayRoutefor1stAccountVPC1:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 1stAccountVPC1CidrBlock
TransitGatewayId: !Ref TransitGatewayId
VPC1TransitGatewayRoutefor1stAccountVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC1PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 1stAccountVPC2CidrBlock
TransitGatewayId: !Ref TransitGatewayId
# 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
VPC2TransitGatewayRouteforSameAccountVPC2:
Type: AWS::EC2::Route
DependsOn: VPC2TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref VPC1CidrBlock
TransitGatewayId: !Ref TransitGatewayId
VPC2TransitGatewayRoutefor1stAccountVPC1:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 1stAccountVPC1CidrBlock
TransitGatewayId: !Ref TransitGatewayId
VPC2TransitGatewayRoutefor1stAccountVPC2:
Type: AWS::EC2::Route
DependsOn: VPC1TransitGatewayAttachment
Properties:
RouteTableId: !Ref VPC2PrivateSubnetForEC2RouteTable
DestinationCidrBlock: !Ref 1stAccountVPC2CidrBlock
TransitGatewayId: !Ref TransitGatewayId
# ------------------------------------------------------------#
# 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
VPC1EC2SecurityGroupIngressFromSameAccountVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC2CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
VPC1EC2SecurityGroupIngressFrom1stAccountVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stAccountVPC1CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
VPC1EC2SecurityGroupIngressFrom1stAccountVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stAccountVPC2CidrBlock
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
VPC2EC2SecurityGroupIngressFromSameAccountVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref VPC1CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
VPC2EC2SecurityGroupIngressFrom1stAccountVPC1EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stAccountVPC1CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
VPC2EC2SecurityGroupIngressFrom1stAccountVPC2EC2:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stAccountVPC2CidrBlock
GroupId: !GetAtt VPC2EC2SecurityGroup.GroupId
以上で完了です。
EC2インスタンスでpingを実行し疎通確認
無事疎通確認が出来ました。
ここまでで勉強になった事
RAMで共有したTransitgatewayは、考えてみれば当たり前ですがリージョナルサービスなので、例えば先程のアカウントBスタックをus-east-1で実行しようとすると以下のようにエラーが起きます。
Resource handler returned message: "Transit Gateway tgw-xxxxxxxxxxxxxxxxx was deleted or does not exist. (Service: Ec2, Status Code: 400, Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)" (RequestToken: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, HandlerErrorCode: NotFound)
これを踏まえてアカウントAのリージョン1と、アカウントBのリージョン2を接続するにはどうしたらいいかを考えてみました。
②別アカウント別リージョンを接続する(3アカウントver)
現在までの理解だと、tgwアカウント内にPeering Attachmentを作成する事で、以下が可能なのではないかと考えました。
(※前回以前からの流れを汲む意図で8VPC(リージョン内、リージョン間、アカウント間)の図を記載していますが、実際に作成するものはシンプルにします。)
この狙いで、
[アカウントA/ap-northeast-1/VPC1]
↓↑
[アカウントB/us-east-1/VPC1]
のような疎通が取れるか確認してみます。
構成図
先ほどの図ではごちゃごちゃとしていましたが、流石に今回は以下のように省略します。
手順
※手順に混乱が起きないよう、コンソールの作業場所を図にしました。(以下は構成図ではないです。)
tgwアカウントのap-northeast-1で以下テンプレートを実行します。
tgw_account_1stRegion.yml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
AccountAId:
Type: String
Resources:
# ------------------------------------------------------------#
# RAM
# ------------------------------------------------------------#
ResourceShare:
Type: AWS::RAM::ResourceShare
DependsOn:
- TransitGateway
Properties:
Name: !Sub ${PJPrefix}-${Environment}-ram
ResourceArns:
- !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:transit-gateway/${TransitGateway}
Principals:
- !Ref AccountAId
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-ram-for-account-a
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
AmazonSideAsn: 64512 # デフォルト値
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: enable
DefaultRouteTablePropagation: enable
DnsSupport: enable
VpnEcmpSupport: enable
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgateway-for-account-a
Outputs:
TransitGatewayId:
Value: !Ref TransitGateway
PeerRegion:
Value: !Ref AWS::Region
PeerTransitGatewayId:
Value: !Ref TransitGateway
↓
同じくtgwアカウントの、今度はus-east-1リージョンで以下テンプレートを実行します。
tgw_account_2ndRegion.yml
※空欄パラメーター値は「tgw_account_1stRegion.yml」スタックの同名出力値をコピペください。
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
AccountBId:
Type: String
PeerRegion: # 1stリージョンのスタックの同名出力値を入力
Type: String
PeerTransitGatewayId: # 1stリージョンのスタックの同名出力値を入力
Type: String
Resources:
# ------------------------------------------------------------#
# RAM
# ------------------------------------------------------------#
ResourceShare:
Type: AWS::RAM::ResourceShare
DependsOn:
- TransitGateway
Properties:
Name: !Sub ${PJPrefix}-${Environment}-ram
ResourceArns:
- !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:transit-gateway/${TransitGateway}
Principals:
- !Ref AccountBId
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-ram-for-account-b
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
AmazonSideAsn: 64512 # デフォルト値
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: enable
DefaultRouteTablePropagation: enable
DnsSupport: enable
VpnEcmpSupport: enable
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgateway-for-account-b
TransitGatewayPeeringAttachment:
Type: AWS::EC2::TransitGatewayPeeringAttachment
Properties:
PeerAccountId: !Ref AWS::AccountId
PeerRegion: !Ref PeerRegion
PeerTransitGatewayId: !Ref PeerTransitGatewayId
TransitGatewayId: !Ref TransitGateway
Outputs:
TransitGatewayId:
Value: !Ref TransitGateway
↓
tgwアカウントのap-northeast-1リージョンの「Transit Gateway アタッチメント」で「Pending Acceptance」状態になっているPeering Attachmentを「アクション」→「Transit Gatewayアタッチメントを承諾」する。
承諾手順
↓
↓
↓
Pending(保留中)になる。
↓
Availableに変わる。(完了)
↓
アカウントAのap-northeast-1のRAMコンソール移動し、保留中のリソース共有(招待)を承認する。(※手順は前章手順「RAM作業」ブロックを参照)
↓
アカウントBのus-east-1のRAMコンソール移動し、保留中のリソース共有(招待)を承認する。(※手順は前章手順「RAM作業」ブロックを参照)
↓
アカウントAのap-northeast-1で以下テンプレートを実行。
AccountA_1stRegion.yml
※「TransitGatewayId」パラメーター値は「tgw_account_1stRegion.yml」スタックの同名出力値をコピペください。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
# for VPC1
VPC1CidrBlock:
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
ImageId: # EC2のImageId
Type: String
Default: ami-079a2a9ac6ed876fc
InstanceType: # EC2のInstanceType(今回は共通)
Type: String
Default: t2.micro
# for 2ndAccount
2ndAccountVPC1CidrBlock:
Type: String
Default: 10.2.0.0/16
# tgw_account.ymlの同名出力値を入力
TransitGatewayId:
Type: String
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
# for VPC1
VPC1TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC1PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGatewayId
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc1
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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 2ndAccountVPC1CidrBlock
TransitGatewayId: !Ref TransitGatewayId
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
VPC1EC2SecurityGroupIngressFrom2ndAccountVPC1CidrBlock:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndAccountVPC1CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
↓
アカウントBのus-east-1で以下テンプレートを実行。
AccountB_2ndRegion.yml
※「TransitGatewayId」パラメーター値は「tgw_account_1stRegion.yml」スタックの同名出力値をコピペください。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
# for VPC1
VPC1CidrBlock:
Type: String
Default: 10.2.0.0/16
VPC1PrivateSubnetForEC2CidrBlock: # VPC1のEC2を配置するサブネットのCIDRブロック
Type: String
Default: 10.2.0.0/24
VPC1PrivateSubnetForTransitGatewayAttachmentCidrBlock: # VPC1のTransittGatewayをアタッチするサブネットのCIDRブロック
Type: String
Default: 10.2.1.0/28
ImageId: # EC2のImageId
Type: String
Default: ami-06e46074ae430fba6
InstanceType: # EC2のInstanceType(今回は共通)
Type: String
Default: t2.micro
# for 1stAccount
1stAccountVPC1CidrBlock:
Type: String
Default: 10.1.0.0/16
# tgw_account.ymlの同名出力値を入力
TransitGatewayId:
Type: String
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
# for VPC1
VPC1TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC1PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGatewayId
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc1
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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 1stAccountVPC1CidrBlock
TransitGatewayId: !Ref TransitGatewayId
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
VPC1EC2SecurityGroupIngressFrom1stAccountVPC1CidrBlock:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stAccountVPC1CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
↓
tgwアカウントのap-northeast-1の「VPC」コンソールに移動して、「Transit Gateway ルートテーブル」→作成済みのTGWルートテーブル ID→「静的ルートを作成」で[10.2.0.0/16]でPeering Attachment向けの静的ルートを追加する。
静的ルート追加手順
↓
↓
↓
同じ要領で、tgwアカウントのus-east-1の「VPC」」コンソールに移動して、「Transit Gateway ルートテーブル」→作成済みのTGWルートテーブル ID→「静的ルートを作成」で[10.1.0.0/16]でPeering Attachment向けの静的ルートを追加する。
※最後の静的ルートの追加はさすがにそれぞれテンプレを作る事はせず手動にしました。
EC2インスタンスでpingを実行し疎通確認
アカウントAのap-northeast-1→アカウントBのus-east-1
アカウントBのus-east-1→アカウントAのap-northeast-1
無事疎通確認が出来ました.
③別アカウント別リージョンを接続する(2アカウントver)
最後に②で作成したものから中間のアカウントを省いたものを作ってみます!
構成図
理解優先Ver
※整えると
無駄なスペースを省いたVer
手順
※こちらも手順に混乱が起きないよう、コンソールの作業場所を図にしました。
アカウントAのap-northeast-1で以下スタックを実行します。
AccountA_1stRegion.yml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
# for VPC1
VPC1CidrBlock:
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
ImageId: # EC2のImageId
Type: String
Default: ami-079a2a9ac6ed876fc
InstanceType: # EC2のInstanceType(今回は共通)
Type: String
Default: t2.micro
# for 2ndAccount
2ndAccountVPC1CidrBlock:
Type: String
Default: 10.2.0.0/16
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
# for VPC1
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
AmazonSideAsn: 64512 # デフォルト値
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: enable
DefaultRouteTablePropagation: enable
DnsSupport: enable
VpnEcmpSupport: enable
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgateway
VPC1TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC1PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc1
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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 2ndAccountVPC1CidrBlock
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
# ------------------------------------------------------------#
# 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
VPC1EC2SecurityGroupIngressFrom2ndAccountVPC1CidrBlock:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 2ndAccountVPC1CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
Outputs:
PeerRegion:
Value: !Ref AWS::Region
PeerTransitGatewayId:
Value: !Ref TransitGateway
↓
アカウントAのus-east-1で以下スタックを実行します。
AccountA_2ndRegion.yml
※パラメーター値「AccountBId」にはAccountBのIDを、「PeerRegion」と「PeerTransitGatewayId」にはAccountA_1stRegion.ymlの同名出力値を入力ください。
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
AccountBId:
Type: String
PeerRegion: # 1stリージョンのスタックの同名出力値を入力
Type: String
PeerTransitGatewayId: # 1stリージョンのスタックの同名出力値を入力
Type: String
Resources:
# ------------------------------------------------------------#
# RAM
# ------------------------------------------------------------#
ResourceShare:
Type: AWS::RAM::ResourceShare
DependsOn:
- TransitGateway
Properties:
Name: !Sub ${PJPrefix}-${Environment}-ram
ResourceArns:
- !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:transit-gateway/${TransitGateway}
Principals:
- !Ref AccountBId
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-ram-for-account-b
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
AmazonSideAsn: 64512 # デフォルト値
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: enable
DefaultRouteTablePropagation: enable
DnsSupport: enable
VpnEcmpSupport: enable
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgateway-for-account-b
TransitGatewayPeeringAttachment:
Type: AWS::EC2::TransitGatewayPeeringAttachment
Properties:
PeerAccountId: !Ref AWS::AccountId
PeerRegion: !Ref PeerRegion
PeerTransitGatewayId: !Ref PeerTransitGatewayId
TransitGatewayId: !Ref TransitGateway
Outputs:
TransitGatewayId:
Value: !Ref TransitGateway
↓
アカウントAのap-northeast1の「VPC」コンソールの「Transit Gateway アタッチメント」で「Pending Acceptance」状態になっているPeering Attachmentを「アクション」→「Transit Gatewayアタッチメントを承諾」します。
↓
アカウントBのus-east-1の「RAM」コンソールに移動し、リソースの共有を承諾します。
↓
アカウントBのus-east-1の「Cloudformation」コンソールに移動し、以下テンプレートを実行します。
AccountB_2ndRegion.yml
※「TransitGatewayId」パラメーター値はAccountA_2ndRegion.ymlスタックの同名出力値をコピペください。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
PJPrefix: # リソース名やNameタグ値の接頭辞に利用
Type: String
Environment: # 同上(環境名)
Type: String
Default: prd
# for VPC1
VPC1CidrBlock:
Type: String
Default: 10.2.0.0/16
VPC1PrivateSubnetForEC2CidrBlock: # VPC1のEC2を配置するサブネットのCIDRブロック
Type: String
Default: 10.2.0.0/24
VPC1PrivateSubnetForTransitGatewayAttachmentCidrBlock: # VPC1のTransittGatewayをアタッチするサブネットのCIDRブロック
Type: String
Default: 10.2.1.0/28
ImageId: # EC2のImageId
Type: String
Default: ami-06e46074ae430fba6
InstanceType: # EC2のInstanceType(今回は共通)
Type: String
Default: t2.micro
# for 1stAccount
1stAccountVPC1CidrBlock:
Type: String
Default: 10.1.0.0/16
# AccountB_2ndRegion.ymlの同名出力値を入力
TransitGatewayId:
Type: String
Resources:
# ------------------------------------------------------------#
# TransitGateway
# ------------------------------------------------------------#
# for VPC1
VPC1TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref VPC1PrivateSubnetForTransitGatewayAttachment
TransitGatewayId: !Ref TransitGatewayId
VpcId: !Ref VPC1
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-${Environment}-transitgatewayattachment-vpc1
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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 1stAccountVPC1CidrBlock
TransitGatewayId: !Ref TransitGatewayId
# ------------------------------------------------------------#
# 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
# ------------------------------------------------------------#
# 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
VPC1EC2SecurityGroupIngressFrom1stAccountVPC1CidrBlock:
Type: AWS::EC2::SecurityGroupIngress
Properties:
FromPort: -1
ToPort: -1
IpProtocol: icmp
CidrIp: !Ref 1stAccountVPC1CidrBlock
GroupId: !GetAtt VPC1EC2SecurityGroup.GroupId
↓
アカウントAのap-northeast-1の「VPC」コンソールに移動して、「Transit Gateway ルートテーブル」→作成済みのTGWルートテーブル ID→「静的ルートを作成」で[10.2.0.0/16]でPeering Attachment向けの静的ルートを追加する。
↓
アカウントAのus-east-1の「VPC」コンソールに移動して、「Transit Gateway ルートテーブル」→作成済みのTGWルートテーブル ID→「静的ルートを作成」で[10.1.0.0/16]でPeering Attachment向けの静的ルートを追加する。
EC2インスタンスでpingを実行し疎通確認
アカウントAのap-northeast-1→アカウントBのus-east-1
アカウントBのus-east-1→アカウントAのap-northeast-1
無事疎通確認が出来ました.
終わりに
構成図でもっとRAMの状態と意図が一目でわかる表現を見つけたいなと思ってしまいました。
お読みいただき有難うございました!
Discussion