VPC creation with CFN

AWS::EC2::VPC - AWS CloudFormation

AWS::EC2::Subnet - AWS CloudFormation

AWS::EC2::NatGateway - AWS CloudFormation

Objective

  • To create AWS VPC,Public Subnets, Private Subnets and NAT Gateway using Cloudformation.

Diagram

VPC CFN (5).jpg

Main Template

AWSTemplateFormatVersion: '2010-09-09'
Description: Creating VPC using CFN

Resources:

# NewVPC

  wynhVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags: 
        - Key: 'Name'
          Value: 'wynhVPC'
        - Key: 'Region'
          Value: 'Singapore'

# public-subnet-1

  pubSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.0.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1a'
      Tags: 
        - Key: 'Name'
          Value: 'pubSubnet1'
        - Key: 'Region'
          Value: 'Singapore'

# public-subnet-2

  pubSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.1.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1b'
      Tags: 
        - Key: 'Name'
          Value: 'pubSubnet2'
        - Key: 'Region'
          Value: 'Singapore'

# public-subnet-3

  pubSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.2.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1c'
      Tags: 
        - Key: 'Name'
          Value: 'pubSubnet3'
        - Key: 'Region'
          Value: 'Singapore'

# private-subnet-1

  privateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.3.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1a'
      Tags: 
        - Key: 'Name'
          Value: 'privateSubnet1'
        - Key: 'Region'
          Value: 'Singapore'

# private-subnet-2

  privateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.4.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1b'
      Tags: 
        - Key: 'Name'
          Value: 'privateSubnet2'
        - Key: 'Region'
          Value: 'Singapore'

# private-subnet-3

  privateSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.5.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1c'
      Tags: 
        - Key: 'Name'
          Value: 'privateSubnet3'
        - Key: 'Region'
          Value: 'Singapore'

# internet-gateway

  wynhIGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags: 
        - Key: 'Name'
          Value: 'wynhIGW'
        - Key: 'Region'
          Value: 'Singapore'

# VPC <--> IGW attachment

  VPCtoIGW:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref wynhVPC
      InternetGatewayId: !Ref wynhIGW

# Public RT

  PublicRT:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref wynhVPC
      Tags: 
        - Key: 'Name'
          Value: 'PublicRT'
        - Key: 'Region'
          Value: 'Singapore'

# Private RT

  PrivateRT:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref wynhVPC
      Tags: 
        - Key: 'Name'
          Value: 'PrivateRT'
        - Key: 'Region'
          Value: 'Singapore'

# PublicSubnet to IGW

  pubRT1toIGW:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRT
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref wynhIGW

# PublicSubnet association with Public RT

  pubSubnet1PublicRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref pubSubnet1
      RouteTableId: !Ref PublicRT

# PublicSubnet 2 association with Public RT

  pubSubnet2PublicRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref pubSubnet2
      RouteTableId: !Ref PublicRT

# PublicSubnet 3 association with Public RT

  pubSubnet3PublicRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref pubSubnet3
      RouteTableId: !Ref PublicRT

# PrivateSubnet 1 association with Private RT

  privateSubnet1PrivateRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref privateSubnet1
      RouteTableId: !Ref PrivateRT

# PrivateSubnet 2 association with Private RT

  privateSubnet2PrivateRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref privateSubnet2
      RouteTableId: !Ref PrivateRT

# PrivateSubnet 3 association with Private RT

  privateSubnet3PrivateRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref privateSubnet3
      RouteTableId: !Ref PrivateRT

  # elastic ip for NAT

  NatGatewayElasticIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: "vpc"
      Tags:
        - Key: "Name"
          Value: "EIP"
        - Key: "region"
          Value: "Singapore"

  #NAT Gateway for private subnet

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGatewayElasticIP.AllocationId
      ConnectivityType: "public"
      SubnetId: !Ref pubSubnet2
      Tags:
        - Key: "Name"
          Value: "NatGateway"
        - Key: "region"
          Value: "Singapore"

  # NAT gateway route in RTB

  NatGWRouteInRTB2:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      RouteTableId: !Ref PrivateRT
      GatewayId: !Ref NatGateway

Let’s break down the code!

Create a new VPC with CIDR 192.168.0.0/16

AWSTemplateFormatVersion: '2010-09-09'
Description: Creating VPC using CFN

Resources:

# NewVPC

  wynhVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags: 
        - Key: 'Name'
          Value: 'wynhVPC'
        - Key: 'Region'
          Value: 'Singapore'

Create 3 Public Subnets and 3 Private Subnets.

# public-subnet-1

  pubSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.0.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1a'
      Tags: 
        - Key: 'Name'
          Value: 'pubSubnet1'
        - Key: 'Region'
          Value: 'Singapore'

# public-subnet-2

  pubSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.1.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1b'
      Tags: 
        - Key: 'Name'
          Value: 'pubSubnet2'
        - Key: 'Region'
          Value: 'Singapore'

# public-subnet-3

  pubSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.2.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1c'
      Tags: 
        - Key: 'Name'
          Value: 'pubSubnet3'
        - Key: 'Region'
          Value: 'Singapore'

# private-subnet-1

  privateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.3.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1a'
      Tags: 
        - Key: 'Name'
          Value: 'privateSubnet1'
        - Key: 'Region'
          Value: 'Singapore'

# private-subnet-2

  privateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.4.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1b'
      Tags: 
        - Key: 'Name'
          Value: 'privateSubnet2'
        - Key: 'Region'
          Value: 'Singapore'

# private-subnet-3

  privateSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref wynhVPC
      CidrBlock: 192.168.5.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: 'ap-southeast-1c'
      Tags: 
        - Key: 'Name'
          Value: 'privateSubnet3'
        - Key: 'Region'
          Value: 'Singapore'

Create a IGW and attached to VPC

# internet-gateway

  wynhIGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags: 
        - Key: 'Name'
          Value: 'wynhIGW'
        - Key: 'Region'
          Value: 'Singapore'

# VPC <--> IGW attachment

  VPCtoIGW:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref wynhVPC
      InternetGatewayId: !Ref wynhIGW

Create route tables for both public and private subnets.

# Public RT

  PublicRT:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref wynhVPC
      Tags: 
        - Key: 'Name'
          Value: 'PublicRT'
        - Key: 'Region'
          Value: 'Singapore'

# Private RT

  PrivateRT:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref wynhVPC
      Tags: 
        - Key: 'Name'
          Value: 'PrivateRT'
        - Key: 'Region'
          Value: 'Singapore'

Make a route for Public subnet to IGW.

# PublicSubnet to IGW

  pubRT1toIGW:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRT
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref wynhIGW
# PublicSubnet association with Public RT

  pubSubnet1PublicRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref pubSubnet1
      RouteTableId: !Ref PublicRT

# PublicSubnet 2 association with Public RT

  pubSubnet2PublicRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref pubSubnet2
      RouteTableId: !Ref PublicRT

# PublicSubnet 3 association with Public RT

  pubSubnet3PublicRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref pubSubnet3
      RouteTableId: !Ref PublicRT

# PrivateSubnet 1 association with Private RT

  privateSubnet1PrivateRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref privateSubnet1
      RouteTableId: !Ref PrivateRT

# PrivateSubnet 2 association with Private RT

  privateSubnet2PrivateRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref privateSubnet2
      RouteTableId: !Ref PrivateRT

# PrivateSubnet 3 association with Private RT

  privateSubnet3PrivateRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref privateSubnet3
      RouteTableId: !Ref PrivateRT

Create a Elastic IP for NAT.

# elastic ip for NAT

  NatGatewayElasticIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: "vpc"
      Tags:
        - Key: "Name"
          Value: "EIP"
        - Key: "region"
          Value: "Singapore"

Create a NAT gateway.

#NAT Gateway for private subnet

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGatewayElasticIP.AllocationId
      ConnectivityType: "public"
      SubnetId: !Ref pubSubnet2
      Tags:
        - Key: "Name"
          Value: "NatGateway"
        - Key: "region"
          Value: "Singapore"

Make a route to NAT gateway for private route table.

# NAT gateway route in RTB

  NatGWRouteInRTB2:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      RouteTableId: !Ref PrivateRT
      GatewayId: !Ref NatGateway

And then, run the aws cli command to execute this. In my case, my stack name is ‘vpc-create’ and my profile is ‘khaw’.

aws cloudformation create-stack --stack-name vpc-create --template-body file://VPC.yaml --profile khaw

Results:

Untitled

Untitled

Untitled

Untitled

Untitled

Untitled

After testing , we can clean up the things by running the delete-stack .

aws cloudformation delete-stack --stack-name vpc-create

:wq!