IaC with AWS CloudFormation

Subash Banjade
4 min readMar 5, 2023

--

Creating VPC, public subnets, private subnets, NAT gateways, and route tables with subnet associations using CloudFormation

AWS CloudFormation

Introduction

CloudFormation is an Infrastructure as a Code concept provided by AWS to automate resource creation using a template. The template can be written in .json or .yaml format. YAML format has been used in this lab. YAML uses indentation to make the code readable and simple. We can create and edit the template using any editor. Sublime Text is used in this lab.

Benefits

Simplify infrastructure management

Quickly replicate your infrastructure

Easily control and track changes to your infrastructure

Templates

A list of resource objects is contained in the Resources object. The attributes of a resource are declared as child objects in a resource declaration. A resource must have a Type attribute that specifies the type of AWS resource to be created. This format of the Type attributes is defined as:

AWS::ProductIdentifier::ResourceType

Creating a VPC

Resources: 

VPC:

Type: AWS::EC2::VPC

Properties:

CidrBlock: 10.0.0.0/16

#ProductIdentifier: EC2

#ResourceType: VPC

Creating subnets in the VPCs

PublicSubnet: 

Type: AWS::EC2::Subnet

Properties:

CidrBlock: 10.0.0.0/24

MapPublicIpOnLaunch: true

VpcId: !Ref VPC



PrivateSubnet:

Type: AWS::EC2::Subnet

Properties:

CidrBlock: 10.0.1.0/24

MapPublicIpOnLaunch: false

VpcId: !Ref VPC
Note: Resources must be declared in every template. 
All these examples will be merged to create a final single template, so Resources is not declared in all of them

Creating custom Route Tables for public subnets

#Public Routing 

PubRouteTable:

Type: AWS::EC2::RouteTable

Properties:

VpcId: !Ref VPC



PublicRoute:

Type: AWS::EC2::Route

DependsOn: VPCGatewayAttachment

Properties:

RouteTableId: !Ref PubRouteTable

DestinationCidrBlock: 0.0.0.0/0

GatewayId: !Ref InternetGateway



PubSubnetRouteTableAssociation:

Type: AWS::EC2::SubnetRouteTableAssociation

Properties:

RouteTableId: !Ref PubRouteTable

SubnetId: !Ref PublicSubnet

Defining Public Security group

 PubSecuritygrp: 

Type: AWS::EC2::SecurityGroup

Properties:

GroupDescription: Public Security group

VpcId: !Ref VPC

SecurityGroupIngress:

- IpProtocol: tcp

FromPort: 80

ToPort: 80

CidrIp: 0.0.0.0/0

- IpProtocol: tcp

FromPort: 22

ToPort: 22

CidrIp: 0.0.0.0/0

Creating NAT Gateway to make private instance access the internet

NatGatewayEIP:

Type: AWS::EC2::EIP

DependsOn: VPCGatewayAttachment

NATGateway:

Type: AWS::EC2::NatGateway

Properties:

SubnetId: !Ref PublicSubnet

AllocationId: !GetAtt NatGatewayEIP.AllocationId
 # Private Security Group

PriSecuritygrp:

Type: AWS::EC2::SecurityGroup

Properties:

GroupDescription: Private SecurityGroup

VpcId: !Ref VPC

SecurityGroupIngress:

- IpProtocol: tcp

FromPort: 80

ToPort: 80

CidrIp: 0.0.0.0/0

- IpProtocol: tcp

FromPort: 22

ToPort: 22

CidrIp: 10.0.0.0/24

Creating custom Route Tables for private subnets

PriRouteTable: 

Type: AWS::EC2::RouteTable

Properties:

VpcId: !Ref VPC



PrivateRoute:

Type: AWS::EC2::Route

Properties:

RouteTableId: !Ref PriRouteTable

DestinationCidrBlock: 0.0.0.0/0

NatGatewayId: !Ref NATGateway



PriSubnetRouteTableAssociation:

Type: AWS::EC2::SubnetRouteTableAssociation

Properties:

SubnetId: !Ref PrivateSubnet

RouteTableId: !Ref PriRouteTable

Creating EC2 instances

PublicEC2: 

Type: AWS::EC2::Instance

Properties:

ImageId: "ami-01cc34ab2709337aa"

KeyName: "vpctest"

InstanceType: "t2.micro"

NetworkInterfaces:

- SubnetId: !Ref PublicSubnet

DeviceIndex: '0'

AssociatePublicIpAddress: "true"

GroupSet:

- !Ref PubSecuritygrp

DependsOn:

- PubRouteTable
PrivateEC2: 

Type: AWS::EC2::Instance

Properties:

ImageId: "ami-01cc34ab2709337aa"

InstanceType: "t2.micro"

KeyName: "vpctest"

NetworkInterfaces:

- SubnetId: !Ref PrivateSubnet

DeviceIndex: '0'

GroupSet:

- !Ref PriSecuritygrp

DependsOn:

- PriRouteTable

Final Template

The final template contains all the resources in a single file. The extension for JSON file is .json and for YAML is .yaml.

Link for the template file

https://github.com/subash7777/CloudFormationCustomVPCSubnetsEC2/blob/main/EditedDesignVPC.yaml

CloudFormation Template snippet from an IDE

Stacks

In AWS CloudFormation, stack refers to the collection of related resources. We can create, update, and delete a collection of resources using stacks.

Creating a stack in CloudFormation

  1. In the AWS Management Console, selecting CloudFormation service and then navigating to create stack option.
  2. Selecting ‘Template is ready’ in ‘Prepare template’ section and specifying upload a template file(‘EditedDesignVPC.yaml).
  3. Then, uploading the created template and selecting next. Then, providing a name for the stack.
  4. Four steps are needed to complete as shown in fig. Various sections are kept as default for this lab.

Note: CloudFormation can only perform actions that you have permission to do.

Cloudformation Stack creating process
Stack creation continued

Configure Stack options >> Review and Create Stack

Then, the details for the stack are generated and events are triggered.

Stack details
Events section

The resources are created as defined in the template. The details for resources can be seen in the resources tab.

Resources section
Resources Create_Complete

The CREATE_IN_PROGRESS flag in stack details changes to CREATE_COMPLETE after the successful execution of the template. Now, we can observe all the resources from their respective sections as given in the figures below.

EC2 instances created
Subnets and route table association

--

--