この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
はじめに
検証のためにVPC間を毎回ピアリングして、ルートテーブルで設定をして、検証後に削除して、再度検証する際にルートテーブルの設定を見落として、1人で「ほげっ?」とかなっている稲村です。
今回は構築というより手順的な要素が強いですが、VPC Peeringの構築で月曜日の寝ぼけた状態でも構築ができるように手順を書いていきたいと思います。
構成図
ハンズオン
構築の流れ
1.VPC-A作成
2.VPC-B + VPC Peering 作成
3.VPC-A(ルートテーブル更新ver)作成
4.リソースの削除順番
※3.VPC-A(ルートテーブル修正ver)
は2.VPC-B + VPC Peering
を参照し、2.VPC-B + VPC Peering
は1.VPC-A
を参照することでVPC Peering
の構築を行うため、削除の順番は3.VPC-A(ルートテーブル修正ver)
で修正した部分を削除しないと、下記画像のような表示が出て、スタックを削除することが出来ません。
上記の順番で構築を行なっていきます。
最終的にピアリング接続のルートテーブルに、各VPCのルートテーブル同士が下記画像のように2つのルートテーブルが表示されれば、それぞれが接続されていることになります。
1.VPC-A作成
まずはVPC-A
を構築します。
後続の手順VPC-B + VPC Peering
を構築した後に、更新する部分はコメントアウトしている(PrivateRouteA Create
)部分です。
AWSTemplateFormatVersion: "2010-09-09"
Description:
VPC,Subnet,IGW,RouteTable, Create
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "Project Name"
Parameters:
- PJName
- Label:
default: "Network Configuration"
Parameters:
- VPCCIDR
- PublicSubnetACIDR
- PublicSubnetCCIDR
- PrivateSubnetACIDR
- PrivateSubnetCCIDR
- UserName
ParameterLabels:
PJName:
default: "PJName"
VPCCIDR:
default: "VPC CIDR"
PublicSubnetACIDR:
default: "PublicSubnetA CIDR"
PublicSubnetCCIDR:
default: "PublicSubnetC CIDR"
PrivateSubnetACIDR:
default: "PrivateSubnetA CIDR"
PrivateSubnetCCIDR:
default: "PrivateSubnetC CIDR"
UserName:
default: "TagsValue UserName"
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
PJName:
Type: String
Default: "cfn-network-A"
VPCCIDR:
Type: String
Default: "172.16.0.0/16"
PublicSubnetACIDR:
Type: String
Default: "172.16.10.0/24"
PublicSubnetCCIDR:
Type: String
Default: "172.16.20.0/24"
PrivateSubnetACIDR:
Type: String
Default: "172.16.30.0/24"
PrivateSubnetCCIDR:
Type: String
Default: "172.16.40.0/24"
UserName:
Type: String
Default: "inamura"
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
# VPC Create
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsSupport: "true"
EnableDnsHostnames: "true"
InstanceTenancy: default
Tags:
- Key: Name
Value: !Sub "${PJName}-vpc"
- Key: User
Value: !Ref UserName
# InternetGateway Create
InternetGateway:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: !Sub "${PJName}-igw"
- Key: User
Value: !Ref UserName
# IGW Attach
InternetGatewayAttachment:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
# Public SubnetA Create
PublicSubnetA:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: !Ref PublicSubnetACIDR
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-public-subnet-a"
- Key: User
Value: !Ref UserName
# Public SubnetC Create
PublicSubnetC:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1c"
CidrBlock: !Ref PublicSubnetCCIDR
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-public-subnet-c"
- Key: User
Value: !Ref UserName
# Private SubnetA Create
PrivateSubnetA:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: !Ref PrivateSubnetACIDR
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-private-subnet-a"
- Key: User
Value: !Ref UserName
# Private SubnetC Create
PrivateSubnetC:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1c"
CidrBlock: !Ref PrivateSubnetCCIDR
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-private-subnet-c"
- Key: User
Value: !Ref UserName
# ------------------------------------------------------------#
# RouteTable
# ------------------------------------------------------------#
# Public RouteTableA Create
PublicRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-public-routetable"
- Key: User
Value: !Ref UserName
# Private RouteTableA Create
PrivateRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-private-routetable"
- Key: User
Value: !Ref UserName
# ------------------------------------------------------------#
# Routing
# ------------------------------------------------------------#
# PublicRouteA Create
PublicRoute:
Type: "AWS::EC2::Route"
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
##### VPC Peering設定後にコメントアウトを削除、スタック削除の場合はこの部分をコメントアウトする#####
# PrivateRoute:
# Type: "AWS::EC2::Route"
# Properties:
# RouteTableId: !Ref PrivateRouteTable
# DestinationCidrBlock: !ImportValue cfn-network-B-vpc-cidr
# VpcPeeringConnectionId: !ImportValue cfn-network-B-private-vpcpeering
#####ここまで###########################################################################
# ------------------------------------------------------------#
# RouteTable Associate
# ------------------------------------------------------------#
# PublicRouteTable Associate SubnetA
PublicSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref PublicRouteTable
# PublicRouteTable Associate SubnetC
PublicSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PublicSubnetC
RouteTableId: !Ref PublicRouteTable
# PrivateRouteTable Associate SubnetA
PrivateSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PrivateSubnetA
RouteTableId: !Ref PrivateRouteTable
# PrivateRouteTable Associate SubnetC
PrivateSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PrivateSubnetC
RouteTableId: !Ref PrivateRouteTable
# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#
Outputs:
# VPC
VPC:
Value: !Ref VPC
Export:
Name: !Sub "${PJName}-vpc"
VPCCIDR:
Value: !Ref VPCCIDR
Export:
Name: !Sub "${PJName}-vpc-cidr"
# Subnet
PublicSubnetA:
Value: !Ref PublicSubnetA
Export:
Name: !Sub "${PJName}-public-subneta"
PublicSubnetC:
Value: !Ref PublicSubnetC
Export:
Name: !Sub "${PJName}-public-subnetc"
PrivateSubnetA:
Value: !Ref PrivateSubnetA
Export:
Name: !Sub "${PJName}-private-subneta"
PrivateSubnetC:
Value: !Ref PrivateSubnetC
Export:
Name: !Sub "${PJName}-private-subnetc"
2.VPC-B + VPC Peering 作成
VPC-Bの構築と併せて、VPC Peeringを構築します。
VPC Peeringを構築するために、接続先(ここではVPC-A
)が必要となるため、構築の順番が2番目となっています。
AWSTemplateFormatVersion: "2010-09-09"
Description:
VPC,Subnet,IGW,RouteTable, Create
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "Project Name"
Parameters:
- PJName
- Label:
default: "Network Configuration"
Parameters:
- VPCCIDR
- PublicSubnetACIDR
- PublicSubnetCCIDR
- PrivateSubnetACIDR
- PrivateSubnetCCIDR
- UserName
ParameterLabels:
PJName:
default: "PJName"
VPCCIDR:
default: "VPC CIDR"
PublicSubnetACIDR:
default: "PublicSubnetA CIDR"
PublicSubnetCCIDR:
default: "PublicSubnetC CIDR"
PrivateSubnetACIDR:
default: "PrivateSubnetA CIDR"
PrivateSubnetCCIDR:
default: "PrivateSubnetC CIDR"
UserName:
default: "TagsValue UserName"
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
PJName:
Type: String
Default: "cfn-network-B"
VPCCIDR:
Type: String
Default: "192.168.0.0/16"
PublicSubnetACIDR:
Type: String
Default: "192.168.10.0/24"
PublicSubnetCCIDR:
Type: String
Default: "192.168.20.0/24"
PrivateSubnetACIDR:
Type: String
Default: "192.168.30.0/24"
PrivateSubnetCCIDR:
Type: String
Default: "192.168.40.0/24"
UserName:
Type: String
Default: "inamura"
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
# VPC Create
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsSupport: "true"
EnableDnsHostnames: "true"
InstanceTenancy: default
Tags:
- Key: Name
Value: !Sub "${PJName}-vpc"
- Key: User
Value: !Ref UserName
# InternetGateway Create
InternetGateway:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: !Sub "${PJName}-igw"
- Key: User
Value: !Ref UserName
# IGW Attach
InternetGatewayAttachment:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
# Public SubnetA Create
PublicSubnetA:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: !Ref PublicSubnetACIDR
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-public-subnet-a"
- Key: User
Value: !Ref UserName
# Public SubnetC Create
PublicSubnetC:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1c"
CidrBlock: !Ref PublicSubnetCCIDR
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-public-subnet-c"
- Key: User
Value: !Ref UserName
# Private SubnetA Create
PrivateSubnetA:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: !Ref PrivateSubnetACIDR
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-private-subnet-a"
- Key: User
Value: !Ref UserName
# Private SubnetC Create
PrivateSubnetC:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1c"
CidrBlock: !Ref PrivateSubnetCCIDR
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-private-subnet-c"
- Key: User
Value: !Ref UserName
# ------------------------------------------------------------#
# RouteTable
# ------------------------------------------------------------#
# Public RouteTableA Create
PublicRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-public-routetable"
- Key: User
Value: !Ref UserName
# Private RouteTableA Create
PrivateRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJName}-private-routetable"
- Key: User
Value: !Ref UserName
# ------------------------------------------------------------#
# VPCPeering
# ------------------------------------------------------------#
VPCPeer:
Type: AWS::EC2::VPCPeeringConnection
Properties:
VpcId: !GetAtt VPC.VpcId
PeerVpcId: !ImportValue cfn-network-A-vpc
Tags:
- Key: "User"
Value: !Ref UserName
# ------------------------------------------------------------#
# Routing
# ------------------------------------------------------------#
# PublicRouteA Create
PublicRoute:
Type: "AWS::EC2::Route"
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
# PrivateRouteA Create attach VPCPeering
PrivateRoute:
Type: "AWS::EC2::Route"
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: !ImportValue cfn-network-A-vpc-cidr
VpcPeeringConnectionId: !GetAtt VPCPeer.Id
# ------------------------------------------------------------#
# RouteTable Associate
# ------------------------------------------------------------#
# PublicRouteTable Associate SubnetA
PublicSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref PublicRouteTable
# PublicRouteTable Associate SubnetC
PublicSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PublicSubnetC
RouteTableId: !Ref PublicRouteTable
# PrivateRouteTable Associate SubnetA
PrivateSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PrivateSubnetA
RouteTableId: !Ref PrivateRouteTable
# PrivateRouteTable Associate SubnetC
PrivateSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PrivateSubnetC
RouteTableId: !Ref PrivateRouteTable
# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#
Outputs:
# VPC
VPC:
Value: !Ref VPC
Export:
Name: !Sub "${PJName}-vpc"
VPCCIDR:
Value: !Ref VPCCIDR
Export:
Name: !Sub "${PJName}-vpc-cidr"
# Subnet
PublicSubnetA:
Value: !Ref PublicSubnetA
Export:
Name: !Sub "${PJName}-public-subneta"
PublicSubnetC:
Value: !Ref PublicSubnetC
Export:
Name: !Sub "${PJName}-public-subnetc"
PrivateSubnetA:
Value: !Ref PrivateSubnetA
Export:
Name: !Sub "${PJName}-private-subneta"
PrivateSubnetC:
Value: !Ref PrivateSubnetC
Export:
Name: !Sub "${PJName}-private-subnetc"
# VPCPeering
VPCPeeringId:
Value: !GetAtt VPCPeer.Id
Export:
Name: !Sub "${PJName}-private-vpcpeering"
3.VPC-A(ルートテーブル更新ver)作成
変更部分のみ抜粋
自身のPrivateRouteTable
に対して、VPC-B
のCIDRと、VPCPeering ID
を参照して、ルートテーブルの更新を行います。
##### VPC Peering設定後にコメントアウトを削除、スタック削除の場合はこの部分をコメントアウトする#####
PrivateRoute:
Type: "AWS::EC2::Route"
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: !ImportValue cfn-network-B-vpc-cidr
VpcPeeringConnectionId: !ImportValue cfn-network-B-private-vpcpeering
#####ここまで###########################################################################
4.リソースの削除順番
4.1. 手順3.VPC-A(ルートテーブル更新ver)
で更新した#
で囲われている部分をコメントアウト又は、削除してCFnのスタックを更新します。
4.2. VPC-B
のCFnスタックを削除する
4.3. VPC-A
のCFnスタックを削除する
挙動の確認
①VPCピアリング接続を確認して、各ルートテーブルに接続されていることが確認できる
単体でVPCPeeringを構築する際のCFn
上記VPCに含めずVPC Peeringのみを構築する際のCFn
ルートテーブルに含めるなどの手動での作業が必要
AWSTemplateFormatVersion: "2010-09-09"
Description: VPC Peering Inviter Create
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "VPCPeering Configuration"
Parameters:
- UserName
ParameterLabels:
UserName:
default: "TagsValue UserName"
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
UserName:
Type: String
Default: "inamura"
# ------------------------------------------------------------#
# Resources
# ------------------------------------------------------------#
Resources:
# ------------------------------------------------------------#
# VPCPeering
# ------------------------------------------------------------#
VPCPeer:
Type: AWS::EC2::VPCPeeringConnection
Properties:
VpcId: !ImportValue cfn-network-A-vpc
PeerVpcId: !ImportValue cfn-network-B-vpc
Tags:
- Key: "User"
Value: !Ref UserName
さいごに
これで月曜の朝にギリギリに起きてもサックリ構築できますし、ルートテーブルの設定を見落として、1人で「ほげっ?」となる心配も少しは減るかと思います。
CloudFormation を使用して VPC 内のメインルートテーブルにルートを追加するにはどうすればよいですか?などを参考にして、ルートテーブルをLambdaで追加させる構築するのが根本的な解決になるかもしれないですが、さっくりやる分には自分はこれくらいで良さそうです。