Amazon Web Services Cloud Formation template for your VPC. Explained.

post-thumb

BY Bogdan Kulbida / ON Dec 29, 2018

In this article we will clarify how to use AWS Cloud Formation (CF) templates in forming your Virtual Private Cloud (VPC) and its network, including private and public subnets, internet gateways, routes, security groups, network access control lists, etc.

There are a lot of good articles written explaining about best practices and how to build your VPC. But if you want to use AWS Cloud Formation templates for your VPC then pay attention. We will explain why you would want to do this and what building blocks you may need in order to form your VPC.

Let’s start with clarifying what is AWS VPC. According to Wikipedia:

“Amazon Virtual Private Cloud is a commercial cloud computing service that provides users a virtual private cloud, by provisioning a logically isolated section of Amazon Web Services Cloud. Enterprise customers are able to access the Amazon Elastic Compute Cloud over an IPsec based virtual private network.”

And here is what AWS tells us what AWS Cloud Formation is:

“AWS CloudFormation is a service that helps you model and set up your Amazon Web Services resources so that you can spend less time managing those resources and more time focusing on your applications that run in AWS. You create a template that describes all the AWS resources that you want (like Amazon EC2 instances or Amazon RDS DB instances), and AWS CloudFormation takes care of provisioning and configuring those resources for you. You don’t need to individually create and configure AWS resources and figure out what’s dependent on what; AWS CloudFormation handles all of that.”

Simply put, a VPC is a software-defined network optimized for performance to transmit network packets into, out of, and across AWS regions. It plays a crucial role in your computing infrastructure placement as well as security. It defines the logical boundaries for your infrastructure within the cloud and protects your assets, if done right.

You can build your VPC in two ways. The simplest way is to use AWS Management Console to create and manage VPCs. However, this approach cannot be automated and usually cannot be incrementally improved since it is hard to measure (read = visualize) and keep track of all the elements used - most likely.

The other way to build your VPCs is to use AWS Cloud Formation. Cloud Formation is a product within the AWS infrastructure that allows you to describe your infrastructure using templates and then apply those templates to automatically provision your cloud resources. Also, using CF visualization tools, you can see your infrastructure at a glance, analyze it and improve it over time, known as the “Infrastructure As Code” (IaC) paradigm.

Here is an example of a simple AWS CF template for forming a simple VPC:


AWSTemplateFormatVersion = "2010-09-09"

Description = >
  This is a simple VPC CloudFormation template

Parameters:

  VPCCIDR:
    Description = CIDR notation for your VPC
    Type = String
    Default = 172.30.0.0/16

  Subnet1CIDR:
    Description = CIDR notation for the public subnet
    Type = String
    Default = 172.30.0.0/24

  Subnet3CIDR:
    Description = CIDR notation for the private subnet
    Type = String
    Default = 172.30.1.0/24

Resources:
  VPC:
    Type = AWS::EC2::VPC
    Properties:
      EnableDnsSupport = 'true'
      EnableDnsHostnames = 'true'
      CidrBlock = !Ref VPCCIDR
      Tags:
      - Key = Application
        Value:
          Ref = AWS::StackId
      - Key = Name
        Value = My VPC

  InternetGateway:
    Type = AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key = Application
        Value:
          Ref = AWS::StackName
      - Key = Network
        Value = Public
      Tags = 
        - Key = Name 
          Value = VPC IG

  PublicSubnet1 = 
    Type = AWS::EC2::Subnet
    Properties:
      VpcId = !Ref VPC
      AvailabilityZone = !Select [ 0, !GetAZs '' ]
      CidrBlock = !Ref Subnet1CIDR
      MapPublicIpOnLaunch = true
      Tags = 
        - Key = Name 
          Value = VPC Public Subnet (AZ1)

  PrivateSubnet1:
    Type = 'AWS::EC2::Subnet'
    Properties:
      VpcId = !Ref VPC
      AvailabilityZone = !Select [ 0, !GetAZs '' ]
      CidrBlock = !Ref Subnet3CIDR
      MapPublicIpOnLaunch = false
      Tags:
        - Key = Name
          Value = VPC Private Subnet (AZ2)

  InternetGateway:
    Type = AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key = Name
          Value = !Join [_, [!Ref 'AWS::StackName']]

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

  PublicRouteTable:
    Type = AWS::EC2::RouteTable
    Properties:
      VpcId = !Ref VPC
      Tags:
        - Key = Name
          Value = !Join [_, [!Ref 'AWS::StackName']]

  PrivateRouteTable:
    Type = AWS::EC2::RouteTable
    Properties:
      VpcId = !Ref VPC

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

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

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

Outputs:
  VPCID:
    Description = VPC ID
    Value = !Ref VPC
  PublicSubnet1:
    Description = Public Subnet 1
    Value = !Ref PublicSubnet1
  PrivateSubnet1:
    Description = Private Subnet 1
    Value = !Ref PrivateSubnet1
  

What this template will provision, once you apply it, is a VPC with public and private subnets and their attachments. Public subnet will be exposed to the Internet, so any resource placed in this subnet will be accessible from the Internet. You may place your web server into it, for example.

Private subnet, on the other hand, does not have public exposure, and so it is more secure and well-suited for database and/or application servers. What is interesting here is the other attachments that you absolutely need in order to achieve such network topology.

Here is a diagram of our VPC:

Even though it may not be clear first, we have few implicit elements here = VPC’s building blocks that allow traffic flow across a wire into and out of our network = GatewayToInternet (GTI), Route, InternetGateway (IG) and a RouteTable (RT). It’s very important to understand that Route and RouteTable are different things = from the physical network, you may have your Router but you forgot to configure connectivity through it. As well as InternetGateway and GatewayToInternet - you may have a device but it may not be connected to the Internet.

When you provision your VPCs you need to be very explicit in your template for the Cloud Formation service what you are actually trying to accomplish, otherwise you may spent hours or days trying to understand why something does not work as you would expect.

Let’s consider a public subnet for a second. To make a subnet to be public, you need to have a Router that must have attachments such as InternetGateway, GatewayToInternet AND a rule in your public RouteTable to allow traffic flow through the Router. Hopefully that makes sense. Here is a visualization of what we just said:

As for the private subnet, things are a little simpler here, you just need to have a private RouteTable that does not have attached Router.

Unless restricted by the Security Groups and/or Network Access Control Lists, it is important to keep in mind that within your VPC all your resources CAN communicate IF, AND ONLY IF, you have route tables that allow traffic flow into and out of your subnets.

Using AWS Cloud Formation templates to provision your infrastructure is a powerful way to quickly and reliably build your cloud infrastructure. You can even combine AWS Cloud Formation templates with other AWS services such as Elastic Beanstalk to achieve higher efficiency.

Here at Konstankino we utilize AWS Cloud Formation as it helps us to spend less time on provisioning services and reduces the chance of making a mistake. Because we are more efficient, we can concentrate on our value-added work, such as writing the code for our customers. Feel free to reach out should you need help with AWS Cloud.

Share: