I tried to create a VPC with AWS CloudFormation

2021.07.15

Introduction

In this post we will create 2 Availability zone VPC using aws CloudFormation Each AZ will have two subnets (public/private), and the public subnet associated with public route table which has internet gateway.

Template

AWSTemplateFormatVersion: 2010-09-09
Description: Deploy a VPC with public/private subnets

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      Tags:
      - Key: Name
        Value: myVPC

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: Name
        Value: myVPC Internet Gateway

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

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: !Select 
        - '0'
        - !GetAZs ''
      Tags:
        - Key: Name
          Value: Public Subnet 1

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select 
        - '0'
        - !GetAZs ''
      Tags:
        - Key: Name
          Value: Private Subnet 1

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select 
        - '1'
        - !GetAZs ''
      Tags:
        - Key: Name
          Value: Public Subnet 2

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: !Select 
        - '1'
        - !GetAZs ''
      Tags:
        - Key: Name
          Value: Private Subnet 2

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: Public Route Table

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

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

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

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
      - Key: Name
        Value: Private Route Table

  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable

Outputs:
  VPC:
    Description: VPC
    Value: !Ref VPC
  AZ1:
    Description: Availability Zone 1
    Value: !GetAtt 
      - PublicSubnet1
      - AvailabilityZone  
  AZ2:
    Description: Availability Zone 2
    Value: !GetAtt 
      - PublicSubnet2
      - AvailabilityZone

Template Link

Template Explanation:

!Ref,!Select,!GetAz and !GetAtt
  1. !Ref - returns the value of the specified resource.
  2. !Select & !GetAZs - the AvailabilityZone is using !Select and !GetAZs functions. Basically, it is retrieving a list of availability zones and referencing the the first element ('0') from the list.
  3. !GetAtt - the AZ1 output is using !GetAtt function to retrieve the attribute of the resources: it is retrieving "AvailabilityZone" attribute from "PublicSubnet1".

Resource and Its Properties

The Type declares the resource being created. The Properties specifies additional information about the resource.

VPC
  1. CidrBlock: IP range of the VPC
  2. EnableDnsHostnames: Indicates whether the instances launched in the VPC get public DNS hostnames. If this attribute is "true", instances in the VPC get public DNS hostnames.
InternetGateway

InternetGateway provide a target in our VPC route tables for internet-routable traffic, and to perform network address translation (NAT) for instances that have been assigned public IPv4 addresses. The "VPCGatewayAttachment" creates relationship between Internet gateway and the VPC.

2 subnets
  1. Public subnet 1: connected to internet via Internet Gateway.
  2. Private subnet 1: no internet connection.

The properties are:

  1. VpcId: refers to the VPC that contains the subnet.
  2. CidrBlock: 0.0.0.0/24 (public), 0.0.1.0/24 (private).
  3. AvailabilityZone: gets the first AZ retrieved from the list of AZs.
RouteTables
Public Route Table

Note that in "PublicRoute" resource, the "DestinationCidrBlock" is set as "0.0.0.0/0" which refers to the traffic bound to the internet, and the traffic is routed to Internet Gateway.

public_route_table.png

As we can see from the public route table, traffic within the VPC (10.0.0.0/16) is routed only to "local".

Private Route Table

private_route_table.png

The Route Tables should be associated to the appropriate subnets:

Output

it returns information about the created resources

Deleting Stack:

delete-stack.png

Resources:

AWS CloudFormation Documentation