Contents

How to create AWS VPC with Cloudformation

Contents
Note

This CloudFormation template creates following resources

  • Public and Private subnets inside Zone A and Zone B and Zone C
  • Internal and External Security Groups
    • Internal SG allows all traffic from VPC CIDR
    • External SG allows all traffic from VPC CIDR
    • External SG allows all traffic from everywhere on port HTTP (80/TCP) and HTTPS (443/TCP)
  • Route 53 private zone
  • DHCP option for VPC so you can use Route 53 private zone
  • NAT GW for private subnets (redundant)
  • Internet GW
Tip
  • Usually you don’t need too many IP addresses on your public subnet, you can try to keep it small.
  • Possibly you will need a lot of IP addresses inside your private subnet, /22 will gove you ~1000 IP adresses.
  • You don’t need to worry about big subnets on AWS because AWS does not support broadcast.

CF

Description:  CF VPC template for DEV Environment.

Parameters:
EnvironmentName:
Description: An environment name that is prefixed to resource names
Type: String
Default: DEVELOPMENT-VPC

HostedZoneName:
Description: Route53 zone name
Type: String
Default: development-vpc-dns

VpcCIDR:
Description: Please enter the IP range (CIDR notation) for this VPC
Type: String
Default: 10.10.0.0/16

PublicSubnet1CIDR:
Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
Type: String
Default: 10.10.0.0/24

PublicSubnet2CIDR:
Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
Type: String
Default: 10.10.1.0/24

PublicSubnet3CIDR:
Description: Please enter the IP range (CIDR notation) for the public subnet in the third Availability Zone
Type: String
Default: 10.10.2.0/24

PrivateSubnet1CIDR:
Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
Type: String
Default: 10.10.4.0/22

PrivateSubnet2CIDR:
Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone
Type: String
Default: 10.10.8.0/22

PrivateSubnet3CIDR:
Description: Please enter the IP range (CIDR notation) for the private subnet in the third Availability Zone
Type: String
Default: 10.10.12.0/22

Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
	CidrBlock: !Ref VpcCIDR
	EnableDnsSupport: true
	EnableDnsHostnames: true
	Tags:
	- Key: Name
		Value: !Ref EnvironmentName

InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
	Tags:
	- Key: Name
		Value: !Ref EnvironmentName

InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
	InternetGatewayId: !Ref InternetGateway
	VpcId: !Ref VPC

PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
	VpcId: !Ref VPC
	AvailabilityZone: !Select [ 0, !GetAZs '' ]
	CidrBlock: !Ref PublicSubnet1CIDR
	MapPublicIpOnLaunch: true
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Ext-${PublicSubnet1CIDR}-(Za)

PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
	VpcId: !Ref VPC
	AvailabilityZone: !Select [ 1, !GetAZs  '' ]
	CidrBlock: !Ref PublicSubnet2CIDR
	MapPublicIpOnLaunch: true
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Ext-${PublicSubnet2CIDR}-(Zb)

PublicSubnet3:
Type: AWS::EC2::Subnet
Properties:
	VpcId: !Ref VPC
	AvailabilityZone: !Select [ 2, !GetAZs  '' ]
	CidrBlock: !Ref PublicSubnet3CIDR
	MapPublicIpOnLaunch: true
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Ext-${PublicSubnet3CIDR}-(Zc)

PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
	VpcId: !Ref VPC
	AvailabilityZone: !Select [ 0, !GetAZs  '' ]
	CidrBlock: !Ref PrivateSubnet1CIDR
	MapPublicIpOnLaunch: false
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Int-${PrivateSubnet1CIDR}-(Za)

PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
	VpcId: !Ref VPC
	AvailabilityZone: !Select [ 1, !GetAZs  '' ]
	CidrBlock: !Ref PrivateSubnet2CIDR
	MapPublicIpOnLaunch: false
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Int-${PrivateSubnet2CIDR}-(Zb)

PrivateSubnet3:
Type: AWS::EC2::Subnet
Properties:
	VpcId: !Ref VPC
	AvailabilityZone: !Select [ 2, !GetAZs  '' ]
	CidrBlock: !Ref PrivateSubnet3CIDR
	MapPublicIpOnLaunch: false
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Int-${PrivateSubnet3CIDR}-(Zc)

NatGateway1EIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
	Domain: vpc

NatGateway2EIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
	Domain: vpc

NatGateway3EIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
	Domain: vpc

NatGateway1:
Type: AWS::EC2::NatGateway
Properties:
	AllocationId: !GetAtt NatGateway1EIP.AllocationId
	SubnetId: !Ref PublicSubnet1

NatGateway2:
Type: AWS::EC2::NatGateway
Properties:
	AllocationId: !GetAtt NatGateway2EIP.AllocationId
	SubnetId: !Ref PublicSubnet2

NatGateway3:
Type: AWS::EC2::NatGateway
Properties:
	AllocationId: !GetAtt NatGateway3EIP.AllocationId
	SubnetId: !Ref PublicSubnet3

PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
	VpcId: !Ref VPC
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Public-RT

DefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachment
Properties:
	RouteTableId: !Ref PublicRouteTable
	DestinationCidrBlock: 0.0.0.0/0
	GatewayId: !Ref InternetGateway

PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
	RouteTableId: !Ref PublicRouteTable
	SubnetId: !Ref PublicSubnet1

PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
	RouteTableId: !Ref PublicRouteTable
	SubnetId: !Ref PublicSubnet2

PublicSubnet3RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
	RouteTableId: !Ref PublicRouteTable
	SubnetId: !Ref PublicSubnet3

PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
	VpcId: !Ref VPC
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Private-RT-(Za)

DefaultPrivateRoute1:
Type: AWS::EC2::Route
Properties:
	RouteTableId: !Ref PrivateRouteTable1
	DestinationCidrBlock: 0.0.0.0/0
	NatGatewayId: !Ref NatGateway1

PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
	RouteTableId: !Ref PrivateRouteTable1
	SubnetId: !Ref PrivateSubnet1

PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
	VpcId: !Ref VPC
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Private-RT-(Zb)

DefaultPrivateRoute2:
Type: AWS::EC2::Route
Properties:
	RouteTableId: !Ref PrivateRouteTable2
	DestinationCidrBlock: 0.0.0.0/0
	NatGatewayId: !Ref NatGateway2

PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
	RouteTableId: !Ref PrivateRouteTable2
	SubnetId: !Ref PrivateSubnet2

PrivateRouteTable3:
Type: AWS::EC2::RouteTable
Properties:
	VpcId: !Ref VPC
	Tags:
	- Key: Name
		Value: !Sub ${EnvironmentName}-Private-RT-(Zc)

DefaultPrivateRoute3:
Type: AWS::EC2::Route
Properties:
	RouteTableId: !Ref PrivateRouteTable3
	DestinationCidrBlock: 0.0.0.0/0
	NatGatewayId: !Ref NatGateway3

PrivateSubnet3RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
	RouteTableId: !Ref PrivateRouteTable3
	SubnetId: !Ref PrivateSubnet3

DNSZone: 
Type: "AWS::Route53::HostedZone"
Properties: 
	Name: !Ref HostedZoneName
	VPCs: 
	- 
		VPCId: !Ref VPC
		VPCRegion: !Ref "AWS::Region"

	HostedZoneTags: 
	- 
		Key: Name
		Value: !Ref HostedZoneName

DHCPOptions:
Type: AWS::EC2::DHCPOptions
Properties: 
	DomainName: !Ref HostedZoneName
	DomainNameServers: 
		- AmazonProvidedDNS
	Tags: 
		- Key: Name
		Value: !Ref HostedZoneName

DHCPAssociation:
Type: AWS::EC2::VPCDHCPOptionsAssociation
Properties: 
	DhcpOptionsId: !Ref DHCPOptions
	VpcId: !Ref VPC

InternalSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
	GroupDescription: !Sub ${EnvironmentName}-Internal
	VpcId: !Ref VPC
	SecurityGroupIngress:
		- IpProtocol: -1
		CidrIp: 10.10.0.0/16
		- IpProtocol: -1
		CidrIp: !Ref VpcCIDR
	SecurityGroupEgress:
		- IpProtocol: -1
		CidrIp: 0.0.0.0/0
	Tags:
		- Key: Name
		Value: !Sub ${EnvironmentName}-Internal
ExternalSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
	GroupDescription: !Sub ${EnvironmentName}-External
	VpcId: !Ref VPC
	SecurityGroupIngress:
		- IpProtocol: -1
		CidrIp: 10.10.0.0/16
		- IpProtocol: -1
		CidrIp: !Ref VpcCIDR
		- IpProtocol: tcp
		FromPort: 80
		ToPort: 80
		CidrIp: 0.0.0.0/0
		- IpProtocol: tcp
		FromPort: 443
		ToPort: 443
		CidrIp: 0.0.0.0/0
	SecurityGroupEgress:
		- IpProtocol: -1
		CidrIp: 0.0.0.0/0 
	Tags:
		- Key: Name
		Value: !Sub ${EnvironmentName}-External
Outputs:
VPC:
Description: A reference to the created VPC
Value: !Ref VPC

DNS:
Description: Created Route 53 zone
Value: !Ref HostedZoneName

PublicSubnets:
Description: A list of the public subnets
Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2, !Ref PublicSubnet3 ]]

PrivateSubnets:
Description: A list of the private subnets
Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2, !Ref PrivateSubnet3 ]]

PublicSubnet1:
Description: A reference to the public subnet in the 1st Availability Zone
Value: !Ref PublicSubnet1

PublicSubnet2:
Description: A reference to the public subnet in the 2nd Availability Zone
Value: !Ref PublicSubnet2

PublicSubnet3:
Description: A reference to the public subnet in the 2nd Availability Zone
Value: !Ref PublicSubnet3

PrivateSubnet1:
Description: A reference to the private subnet in the 1st Availability Zone
Value: !Ref PrivateSubnet1

PrivateSubnet2:
Description: A reference to the private subnet in the 2nd Availability Zone
Value: !Ref PrivateSubnet2

PrivateSubnet3:
Description: A reference to the private subnet in the 2nd Availability Zone
Value: !Ref PrivateSubnet3