目次
はじめに
こんにちは新入社員のタナミです。
VPCの構築ではCIDRの設定やルートテーブルのアタッチなど、意外と手間が多いように感じます。
そこで、今回はCloudFormationを使ってVPCを作成しようと思います。
今回作成できるもの
今回のCloudFormationでは下記のようなリソースを作成します。
また、ここには載っていませんが自身のIPを許可したセキュリティグループも同時に作成されます。

テンプレートを書こう
CloudFormationで扱うテンプレートの作成を行います。
現在CloudFormationではJSONとYAMLの二つの形式に対応しているので、今回はYAMLでテンプレートを作っていきます。
vpc-automatic.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Parameterized VPC and Security Groups template'
Parameters:
# リソース名のパラメータ
ResourceName:
Type: String
Description: Enter resource name
Default: test
# 自身のIPアドレスを入力
MyIP:
Type: String
Description: Enter your IP
Default: 0.0.0.0/0
# VPC CIDRのパラメータ
VpcCidr:
Type: String
Description: CIDR block for the VPC
Default: 10.0.0.0/16
# パブリックサブネットのCIDRパラメータ
PublicSubnetPrimaryCidr:
Type: String
Description: CIDR block for the primary public subnet
Default: 10.0.1.0/24
PublicSubnetSecondaryCidr:
Type: String
Description: CIDR block for the secondary public subnet
Default: 10.0.2.0/24
PublicSubnetTertiaryCidr:
Type: String
Description: CIDR block for the tertiary public subnet
Default: 10.0.3.0/24
# プライベートサブネットのCIDRパラメータ
PrivateSubnetPrimaryCidr:
Type: String
Description: CIDR block for the primary private subnet
Default: 10.0.101.0/24
PrivateSubnetSecondaryCidr:
Type: String
Description: CIDR block for the secondary private subnet
Default: 10.0.102.0/24
PrivateSubnetTertiaryCidr:
Type: String
Description: CIDR block for the tertiary private subnet
Default: 10.0.103.0/24
Resources:
# VPCを作成
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub '${ResourceName}-vpc'
# インターネットゲートウェイを作成
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub '${ResourceName}-igw'
# VPCをインターネットゲートウェイにアタッチ
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# パブリックルートテーブルを作成
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${ResourceName}-public-route-table'
# プライベートルートテーブルを作成
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${ResourceName}-private-route-table'
# パブリックルートテーブルをインターネットゲートウェイにアタッチ
PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
# パブリックサブネットを作成
PublicSubnetPrimary:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetPrimaryCidr
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${ResourceName}-public-subnet-primary'
PublicSubnetSecondary:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetSecondaryCidr
AvailabilityZone: !Select [1, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${ResourceName}-public-subnet-secondary'
PublicSubnetTertiary:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetTertiaryCidr
AvailabilityZone: !Select [2, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${ResourceName}-public-subnet-tertiary'
# プライベートサブネットを作成
PrivateSubnetPrimary:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnetPrimaryCidr
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub '${ResourceName}-private-subnet-primary'
PrivateSubnetSecondary:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnetSecondaryCidr
AvailabilityZone: !Select [1, !GetAZs '']
Tags:
- Key: Name
Value: !Sub '${ResourceName}-private-subnet-secondary'
PrivateSubnetTertiary:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnetTertiaryCidr
AvailabilityZone: !Select [2, !GetAZs '']
Tags:
- Key: Name
Value: !Sub '${ResourceName}-private-subnet-tertiary'
# パブリックサブネットをルートテーブルに割り当て
PublicSubnetPrimaryRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetPrimary
RouteTableId: !Ref PublicRouteTable
PublicSubnetSecondaryRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetSecondary
RouteTableId: !Ref PublicRouteTable
PublicSubnetTertiaryRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetTertiary
RouteTableId: !Ref PublicRouteTable
# プライベートサブネットをルートテーブルに割り当て
PrivateSubnetPrimaryRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnetPrimary
RouteTableId: !Ref PrivateRouteTable
PrivateSubnetSecondaryRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnetSecondary
RouteTableId: !Ref PrivateRouteTable
PrivateSubnetTertiaryRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnetTertiary
RouteTableId: !Ref PrivateRouteTable
# セキュリティグループを作成
MainSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${ResourceName}-main-sg'
GroupDescription: Security group for my ip
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: -1
CidrIp: !Ref MyIP
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Sub '${ResourceName}-main-sg'
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub '${ResourceName}-vpc'
PublicSubnetPrimaryId:
Description: Public Subnet Primary ID
Value: !Ref PublicSubnetPrimary
Export:
Name: !Sub '${ResourceName}-public-subnet-primary'
PublicSubnetSecondaryId:
Description: Public Subnet Secondary ID
Value: !Ref PublicSubnetSecondary
Export:
Name: !Sub '${ResourceName}-public-subnet-secondary'
PublicSubnetTertiaryId:
Description: Public Subnet Tertiary ID
Value: !Ref PublicSubnetTertiary
Export:
Name: !Sub '${ResourceName}-public-subnet-tertiary'
PrivateSubnetPrimaryId:
Description: Private Subnet Primary ID
Value: !Ref PrivateSubnetPrimary
Export:
Name: !Sub '${ResourceName}-private-subnet-primary'
PrivateSubnetSecondaryId:
Description: Private Subnet Secondary ID
Value: !Ref PrivateSubnetSecondary
Export:
Name: !Sub '${ResourceName}-private-subnet-secondary'
PrivateSubnetTertiaryId:
Description: Private Subnet Tertiary ID
Value: !Ref PrivateSubnetTertiary
Export:
Name: !Sub '${ResourceName}-private-subnet-tertiary'
MainSecurityGroupId:
Description: Main Security Group ID
Value: !Ref MainSecurityGroup
Export:
Name: !Sub '${ResourceName}-main-sg'
CloudFormationを作成しよう
コードが出来たのでCloudFormationの作成に移ります。
スタックの作成から新しいリソースを使用を選択し
下記のようにテンプレートファイルを追加します。

また今回のCloudFormationでは、リソース名とCIDRを自由に設定できるようにしたので設定をしていきます。
さらに、MyIPのパラメーターでセキュリティグループに割り当てる自身のIPを指定します。

これによりスタックが作成され、スタックのステータスがCREATE_COMPLETEとなればリソースの作成完了です。
削除時の注意点
今回作成したスタックの削除を行う時にVPC上にデプロイされたリソースがある場合、削除が実行されません。
特にテンプレート以外から作成したセキュリティグループなどもスタックの削除が実行されない原因になるのでご注意ください。
まとめ
いかがでしたでしょうか。
今回はCloudFormationを使ってVPCの作成を行いました。
このCloudFormationを使うことで次回以降、同様のリソースを作成する際の時短になるかと思いますのでぜひ活用してみて下さい。
よろしくお願いします。