You can support us by downloading this article as PDF from the Link below. Download the guide as PDF

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.

Create CloudFormation Stack

On the drop-down menu, select create stack with new resources. As below image.

Create CloudFormation Stack with New Resources

On the create stack window, select upload a template. Then, choose the file/script you created in the above section. Click next.

Upload The CloudFormation Template

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.

Enter Stack Name and Parameters

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.

Watch Stack Creation Events

When the template creation is complete, you will have all the resources on that Template created. Your Network Architecture is now ready.

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

You can support us by downloading this article as PDF from the Link below. Download the guide as PDF

LEAVE A REPLY

Please enter your comment!
Please enter your name here