How to use Cloudformation to create a VPC on AWS

Using Cloudformation, we can create and manage AWS resources very easily.  Cloudformation can be used to manage all AWS resources using a text file. Cloudformation allows us to create and model our infrastructure and applications without having to perform actions manually. Cloudformation helps us to manage our complete infrastructure in a text file, or template. Cloudformation template is a formatted text file in JSON or YAML language that describes our AWS infrastructure. 

In this article, we will see a Cloudformation to create a VPC with 2 Public and 2 Private Subnets.

Pre-requisites

  1. AWS Account (Create if you don’t have one). 
  2. Basic understanding of Cloudformation Templates.

What we will do?

  1. Login to AWS.
  2. Create a template.
  3. Create a Cloudformation Stack 

Login to AWS

  1. Click here to go to AWS Login Page.

When we hit the above link, we will see a web page as follows where we are required to login using our login details.

Login to AWS

Once we login into AWS successfully, we will see the main console with all the services listed as follows.

AWS Management Console

Create a template

Before we proceed with creating a stack, we should have a template that will be used to create a VPC. Copy the following code and save in on a local machine.

---
AWSTemplateFormatVersion: 2010-09-09
Description: >
  This Templates creates a VPC with 3 public and 3 private subnets.
Parameters:
  VpcCIDR:
    TypeString
    DescriptionVPC CIDR (Do Not Change if no customization is required). 
    Default10.10.0.0/16
  PrivateAZ1SubnetCIDR:
    TypeString
    DescriptionSubnet CIDR for 1st Availability Zone (Do Not Change if no customization is required).
    Default10.10.80.0/21
  PrivateAZ2SubnetCIDR:
    TypeString
    DescriptionSubnet CIDR for 2nd Availability Zone (Do Not Change if no customization is required).
    Default10.10.88.0/21
  PrivateAZ3SubnetCIDR:
    TypeString
    DescriptionSubnet CIDR for 3rd Availability Zone (Do Not Change if no customization is required).
    Default10.10.96.0/21
  PublicAZ1SubnetCIDR:
    TypeString
    DescriptionSubnet CIDR for 1st Availability Zone (Do Not Change if no customization is required).
    Default10.10.0.0/21
  PublicAZ2SubnetCIDR:
    TypeString
    DescriptionSubnet CIDR for 2nd Availability Zone (Do Not Change if no customization is required).
    Default10.10.8.0/21
  PublicAZ3SubnetCIDR:
    TypeString
    DescriptionSubnet CIDR for 3rd Availability Zone (Do Not Change if no customization is required). 
    Default10.10.16.0/21
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          defaultVPC
        Parameters:
          - VpcCIDR
      - Label:
          defaultAvailabilty Zone 1
        Parameters:
          - PublicAZ1SubnetCIDR
          - PrivateAZ1SubnetCIDR
      - Label:
          defaultAvailabilty Zone 1
        Parameters:
          - PublicAZ2SubnetCIDR
          - PrivateAZ2SubnetCIDR
      - Label:
          defaultAvailabilty Zone 1
        Parameters:
          - PublicAZ3SubnetCIDR
          - PrivateAZ3SubnetCIDR
Resources:
  Vpc:
    TypeAWS::EC2::VPC
    Properties:
      CidrBlock!Ref VpcCIDR
      Tags:
        - KeyName
          Value!Sub ${AWS::StackName}
  InternetGateway:
    TypeAWS::EC2::InternetGateway
    Properties:
      Tags:
        - KeyName
          Value!Sub ${AWS::StackName}
  VPCGatewayAttachment:
    TypeAWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId!Ref InternetGateway
      VpcId!Ref Vpc
  # Public Subnets - Route Table
  PublicRouteTable:
    TypeAWS::EC2::RouteTable
    Properties:
      VpcId!Ref Vpc
      Tags:
        - KeyName
          Value!Sub ${AWS::StackName}-public
        - KeyType
          Valuepublic
  PublicSubnetsRoute:
    TypeAWS::EC2::Route
    Properties:
      RouteTableId!Ref PublicRouteTable
      DestinationCidrBlock0.0.0.0/0
      GatewayId!Ref InternetGateway
    DependsOnVPCGatewayAttachment
  # Public Subnets
  PublicAZ1Subnet:
    TypeAWS::EC2::Subnet
    Properties:
      VpcId!Ref Vpc
      CidrBlock!Ref PublicAZ1SubnetCIDR
      AvailabilityZone!Select [0!GetAZs ""]
      MapPublicIpOnLaunchtrue
      Tags:
        - KeyName
          Value!Sub
            - ${AWS::StackName}-public-${AZ}
            - { AZ!Select [0!GetAZs ""] }
        - KeyType
          Valuepublic
  PublicAZ1SubnetRouteTableAssociation:
    TypeAWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId!Ref PublicAZ1Subnet
      RouteTableId!Ref PublicRouteTable
  PublicAZ2Subnet:
    TypeAWS::EC2::Subnet
    Properties:
      VpcId!Ref Vpc
      CidrBlock!Ref PublicAZ2SubnetCIDR
      AvailabilityZone!Select [1!GetAZs ""]
      MapPublicIpOnLaunchtrue
      Tags:
        - KeyName
          Value!Sub
            - ${AWS::StackName}-public-${AZ}
            - { AZ!Select [1!GetAZs ""] }
        - KeyType
          Valuepublic
  PublicAZ2SubnetRouteTableAssociation:
    TypeAWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId!Ref PublicAZ2Subnet
      RouteTableId!Ref PublicRouteTable
  PublicAZ3Subnet:
    TypeAWS::EC2::Subnet
    Properties:
      VpcId!Ref Vpc
      CidrBlock!Ref PublicAZ3SubnetCIDR
      AvailabilityZone!Select [2!GetAZs ""]
      MapPublicIpOnLaunchtrue
      Tags:
        - KeyName
          Value!Sub
            - ${AWS::StackName}-public-${AZ}
            - { AZ!Select [2!GetAZs ""] }
        - KeyType
          Valuepublic
  PublicAZ3SubnetRouteTableAssociation:
    TypeAWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId!Ref PublicAZ3Subnet
      RouteTableId!Ref PublicRouteTable
  # Private Subnets - NAT Gateways
  AZ1NatGatewayEIP:
    TypeAWS::EC2::EIP
    Properties:
      Domainvpc
    DependsOnVPCGatewayAttachment
  AZ1NatGateway:
    TypeAWS::EC2::NatGateway
    Properties:
      AllocationId!GetAtt AZ1NatGatewayEIP.AllocationId
      SubnetId!Ref PublicAZ1Subnet
  AZ2NatGatewayEIP:
    TypeAWS::EC2::EIP
    Properties:
      Domainvpc
    DependsOnVPCGatewayAttachment
  AZ2NatGateway:
    TypeAWS::EC2::NatGateway
    Properties:
      AllocationId!GetAtt AZ2NatGatewayEIP.AllocationId
      SubnetId!Ref PublicAZ2Subnet
  AZ3NatGatewayEIP:
    TypeAWS::EC2::EIP
    Properties:
      Domainvpc
    DependsOnVPCGatewayAttachment
  AZ3NatGateway:
    TypeAWS::EC2::NatGateway
    Properties:
      AllocationId!GetAtt AZ3NatGatewayEIP.AllocationId
      SubnetId!Ref PublicAZ3Subnet
  # Private Subnets
  PrivateAZ1Subnet:
    TypeAWS::EC2::Subnet
    Properties:
      VpcId!Ref Vpc
      CidrBlock!Ref PrivateAZ1SubnetCIDR
      AvailabilityZone!Select [0!GetAZs ""]
      Tags:
        - KeyName
          Value!Sub
            - ${AWS::StackName}-private-${AZ}
            - { AZ!Select [0!GetAZs ""] }
        - KeyType
          Valueprivate
  PrivateAZ1RouteTable:
    TypeAWS::EC2::RouteTable
    Properties:
      VpcId!Ref Vpc
      Tags:
        - KeyName
          Value!Sub
            - ${AWS::StackName}-private-${AZ}
            - { AZ!Select [0!GetAZs ""] }
        - KeyType
          Valueprivate
  PrivateAZ1Route:
    TypeAWS::EC2::Route
    Properties:
      RouteTableId!Ref PrivateAZ1RouteTable
      DestinationCidrBlock0.0.0.0/0
      NatGatewayId!Ref AZ1NatGateway
  PrivateAZ1RouteTableAssociation:
    TypeAWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId!Ref PrivateAZ1Subnet
      RouteTableId!Ref PrivateAZ1RouteTable
  PrivateAZ2Subnet:
    TypeAWS::EC2::Subnet
    Properties:
      VpcId!Ref Vpc
      CidrBlock!Ref PrivateAZ2SubnetCIDR
      AvailabilityZone!Select [1!GetAZs ""]
      Tags:
        - KeyName
          Value!Sub
            - ${AWS::StackName}-private-${AZ}
            - { AZ!Select [1!GetAZs ""] }
        - KeyType
          Valueprivate
  PrivateAZ2RouteTable:
    TypeAWS::EC2::RouteTable
    Properties:
      VpcId!Ref Vpc
      Tags:
        - KeyName
          Value!Sub
            - ${AWS::StackName}-private-${AZ}
            - { AZ!Select [1!GetAZs ""] }
        - KeyType
          Valueprivate
  PrivateAZ2Route:
    TypeAWS::EC2::Route
    Properties:
      RouteTableId!Ref PrivateAZ2RouteTable
      DestinationCidrBlock0.0.0.0/0
      NatGatewayId!Ref AZ2NatGateway
  PrivateAZ2RouteTableAssociation:
    TypeAWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId!Ref PrivateAZ2Subnet
      RouteTableId!Ref PrivateAZ2RouteTable
  PrivateAZ3Subnet:
    TypeAWS::EC2::Subnet
    Properties:
      VpcId!Ref Vpc
      CidrBlock!Ref PrivateAZ3SubnetCIDR
      AvailabilityZone!Select [2!GetAZs ""]
      Tags:
        - KeyName
          Value!Sub
            - ${AWS::StackName}-private-${AZ}
            - { AZ!Select [2!GetAZs ""] }
        - KeyType
          Valueprivate
  PrivateAZ3RouteTable:
    TypeAWS::EC2::RouteTable
    Properties:
      VpcId!Ref Vpc
      Tags:
        - KeyName
          Value!Sub
            - ${AWS::StackName}-private-${AZ}
            - { AZ!Select [2!GetAZs ""] }
        - KeyType
          Valueprivate
  PrivateAZ3Route:
    TypeAWS::EC2::Route
    Properties:
      RouteTableId!Ref PrivateAZ3RouteTable
      DestinationCidrBlock0.0.0.0/0
      NatGatewayId!Ref AZ3NatGateway
  PrivateAZ3RouteTableAssociation:
    TypeAWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId!Ref PrivateAZ3Subnet
      RouteTableId!Ref PrivateAZ3RouteTable
  
Outputs:
  VpcId:
    DescriptionVPC Id
    Value!Ref Vpc
    Export:
      Name!Sub "${AWS::StackName}-VPC-ID"

Create a Cloudformation Stack

To create a Cloudformation Stack, click on “Services” in the top left and search for “Cloudformation”.

Cloudformation Stack

On the main dashboard, click on “Create stack” -> "With new resorces(standard)".

Create Stack

The stack needs a template file which can be a local file or an object file in the S3 Bucket. Since we will be having a local template, click on “Template is ready” -> “Upload a template file”, click on “Choose file” and select the local template file and proceed further.

Stack template

Give a name to the stack, keep all other parameters unchanged.

Stack name and parameters

Give Tags if required.

Tags

Scroll down the page and click on “Create stack”

Create stack

This will take some time, wait till then.

My VPC

You can see the status or event taking place under “Events” tab.

Events

Now, you can go to VPC and check for the VPC that got created. To go to VPC, click on “Services” at the top and left search for VPC.

AWS VPC

In the main dashboard, you can see the number of VPC, Subnets, Route Tables, Internet Gateway, Nat Gateway which got created.

Launch VPC

You can delete the VPC by just deleting the Stack if you no more need it.

List of created Stacks

Conclusion

In this article, we saw the steps to create a Cloudformation Stack to create a VPC with 2 Public and 2 Private Subnet.

Share this page:

0 Comment(s)