The article guides the user on automating infrastructure deployment on AWS using CloudFormation. The template specifically automates the creation of:
- A Virtual Private Network
- An Internet Gateway
- 2 NAT Gateways
- Routing Tables, Routes, and Route Table Associations
- Subnets (Private and Public)
Prerequisites
- An AWS account.
- A user with permissions to create resources on the account. Especially CloudFormation Full access rights.
- An IDE like visual studio editor to write and edit your scripts is unnecessary but will be convenient.
The CloudFormation Template
The below script is used to automate the creation of the network infrastructure as explained above. The user can modify the template to specifics to suit his/her preferred needs. The parts to be modified include:
- The chosen CIDR Blocks for the VPC and Subnets.
- The subnets to be created.
- The NAT gateways to be created.
- The Names and Tags for all the resources created.
---
AWSTemplateFormatVersion: "2010-09-09"
Description: Template to Create our a test environment Network Architecture with 4 private subnets and 2 public subnets
Parameters:
VPCBlock:
Type: String
Description: The CIDR Block for the VPC
Default: 192.168.0.0/16
PrivateSubnet01Block:
Type: String
Description: The CIDR Block for the private subnet 01
Default: 192.168.1.0/26
PrivateSubnet02Block:
Type: String
Description: The CIDR Block for the private subnet 02
Default: 192.168.1.64/26
PrivateSubnet03Block:
Type: String
Description: The CIDR Block for the private subnet 03
Default: 192.168.1.128/26
PrivateSubnet04Block:
Type: String
Description: The CIDR Block for the private subnet 04
Default: 192.168.1.192/26
PublicSubnet01Block:
Type: String
Description: The CIDR Block for the public subnet 01
Default: 192.168.0.0/28
PublicSubnet02Block:
Type: String
Description: The CIDR Block for the public subnet 02
Default: 192.168.0.16/28
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCBlock
EnableDnsHostnames: true
EnableDnsSupport: true
InstanceTenancy: default
Tags:
- Key: Name
Value: eu-central-1-test-Environment-VPC
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
IGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: eu-central-1-test-Environment-IGW
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref IGW
VpcId: !Ref VPC
NatGateway01:
DependsOn:
- PublicSubnet01
- VPCGatewayAttachment
Type: AWS::EC2::NatGateway
Properties:
AllocationId: eipalloc-***************
SubnetId: !Ref PublicSubnet01
Tags:
- Key: Name
Value: eu-central-1-test-Environment-NatGateway01
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
NatGateway02:
DependsOn:
- PublicSubnet02
- VPCGatewayAttachment
Type: AWS::EC2::NatGateway
Properties:
AllocationId: eipalloc-******************
SubnetId: !Ref PublicSubnet02
Tags:
- Key: Name
Value: eu-central-1-test-Environment-NatGateway02
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: eu-central-1-test-Environment-PublicRouteTable
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PrivateRouteTable01:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: eu-central-1-test-Environment-PrivateRouteTable01
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PrivateRouteTable02:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: eu-central-1-test-Environment-PrivateRouteTable02
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PublicRoute:
DependsOn: VPCGatewayAttachment
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref IGW
PrivateRoute01:
DependsOn:
- VPCGatewayAttachment
- NatGateway01
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable01
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway01
PrivateRoute02:
DependsOn:
- VPCGatewayAttachment
- NatGateway02
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable02
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway02
PrivateSubnet01:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: eu-central-1a
CidrBlock: !Ref PrivateSubnet01Block
VpcId: !Ref VPC
Tags:
- Key: Name
Value: eu-central-1-test-Environment-PrivateSubnet01
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PrivateSubnet02:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: eu-central-1b
CidrBlock: !Ref PrivateSubnet02Block
VpcId: !Ref VPC
Tags:
- Key: Name
Value: eu-central-1-test-Environment-PrivateSubnet02
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PrivateSubnet03:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: eu-central-1a
CidrBlock: !Ref PrivateSubnet03Block
VpcId: !Ref VPC
Tags:
- Key: Name
Value: eu-central-1-test-Environment-PrivateSubnet03
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PrivateSubnet04:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: eu-central-1b
CidrBlock: !Ref PrivateSubnet04Block
VpcId: !Ref VPC
Tags:
- Key: Name
Value: eu-central-1-test-Environment-PrivateSubnet04
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PublicSubnet01:
Type: AWS::EC2::Subnet
Properties:
MapPublicIpOnLaunch: true
AvailabilityZone: eu-central-1a
CidrBlock: !Ref PublicSubnet01Block
VpcId: !Ref VPC
Tags:
- Key: Name
Value: eu-central-1-test-Environment-PublicSubnet01
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PublicSubnet02:
Type: AWS::EC2::Subnet
Properties:
MapPublicIpOnLaunch: true
AvailabilityZone: eu-central-1b
CidrBlock: !Ref PublicSubnet02Block
VpcId: !Ref VPC
Tags:
- Key: Name
Value: eu-central-1-test-Environment-PublicSubnet02
- Key: createdBy
Value: Maureen Barasa
- Key: Project
Value: test-blog
- Key: Environment
Value: test
PublicSubnet01RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet01
RouteTableId: !Ref PublicRouteTable
PublicSubnet02RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet02
RouteTableId: !Ref PublicRouteTable
PrivateSubnet01RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet01
RouteTableId: !Ref PrivateRouteTable01
PrivateSubnet02RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet02
RouteTableId: !Ref PrivateRouteTable02
PrivateSubnet03RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet03
RouteTableId: !Ref PrivateRouteTable01
PrivateSubnet04RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet04
RouteTableId: !Ref PrivateRouteTable02
Outputs:
PublicSubnet01Id:
Description: Public Subnet 01 ID in the VPC
Value: !Ref PublicSubnet01
Export:
Name: !Sub "${AWS::StackName}-PublicSubnet01Id"
PublicSubnet02Id:
Description: Public Subnet 02 ID in the VPC
Value: !Ref PublicSubnet02
Export:
Name: !Sub "${AWS::StackName}-PublicSubnet02Id"
PrivateSubne01tId:
Description: Private Subnet 01 ID in the VPC
Value: !Ref PrivateSubnet01
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnetId"
PrivateSubne02tId:
Description: Private Subnet 02 ID in the VPC
Value: !Ref PrivateSubnet02
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnet02Id"
PrivateSubne03tId:
Description: Private Subnet 03 ID in the VPC
Value: !Ref PrivateSubnet03
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnet03Id"
PrivateSubne04tId:
Description: Private Subnet IDs in the VPC
Value: !Ref PrivateSubnet04
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnet04Id"
VpcId:
Description: The VPC Id
Value: !Ref VPC
Export:
Name: !Sub "${AWS::StackName}-VPCID"
The Template/Script Explained
Our Template has three sections:
The Parameter Section: The section allows a user to input custom values for the resources they are creating. It is best for use with dynamic values. Those values that will change regularly on your template.
The Resources Section: This section allows the user to define the AWS resources they want to create using the template.
The Output Section: The section, contains the names of the created resources. Also, should there be need to export these resources to be used on other stacks, the output section provides this option via the export session.
Create a Stack to Execute the Template
Once done editing your script/template login to your AWS cloud account. Under services search for CloudFormation. Then on the CloudFormation console, click on create stack as per image below.
On the drop-down menu, select create stack with new resources. As below image.
On the create stack window, select upload a template. Then, choose the file/script you created in the above section. Click next.
The window that opens allows the user to enter the stack name and Template Parameters. Here the User can decide to change the Template default values to their own customized values. When done click next.
On the subsequent window, configure stack options. This include, the tags, stack policy, rollback configurations, etc. Once done click next. This will open a review window, to check all the configurations done earlier. If the user is satisfied, they can then click on create stack.
Also, as the resources are being created using the template, the user can watch the events on the CloudFormation console. See below image.
When the template creation is complete, you will have all the resources on that Template created. Your Network Architecture is now ready.
Important Links
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-ug.pdf
Happy Building
More Articles on AWS:
How To Stream Logs in AWS from CloudWatch to ElasticSearch
Setup Elasticsearch Cluster with Kibana on AWS
Grant Developers Access to EKS Kubernetes Cluster
Install Istio Service Mesh in EKS Kubernetes Cluster