How to Deploy a VPC using Cloud Formation in AWS?

Share

Note: This blog assumes that you already know how to create a VPC using AWS web console  and have a clear understand of it’s architecture and requirements, if you are new to Cloud Formation please refer this blog for basic understand of what it is.

What are Parameters, Resources, Outputs in an AWS Cloud Formation template?

Parameters

when you want to allow  any user input while creating a stack like name of a s3 bucket  or if  you want to reuse the same template it’s not recommended to hardcode all the details of your resources rather you can give these details using parameters, let’s see this while creating the stack in aws console, and  it’s completely optional to define parameters in a template , below is an example parameter which is intended to be used for a VPC CIDR.

Parameters:
  VpcCIDR:
    Default: 10.0.0.0/16
    Description: Please enter the CIDR (IP range) for this VPC
    Type: String

all the parameters that you declare in a template should be under Parameters: tag only and VpcCIDR: is the  logical names  it can be any alpha alphanumeric value and it should  be unique from all the logical names that were defined with in a template as one can refer to this parameter with this logical name only, different parameter types allowed string , number, list of numbers, comma-delimited list , the type of value allowed for a particular parameter is declared under Type:, and the value given for Default: key word will be used by cloud formation for  creating the stack/infrastructure if no other value is given by the user while creating the stack.

Resources

there more than 200 plus resources available in aws  , the infrastructure that you want to deploy should be declared under Resources tag in configuration file , and every resource will have its own properties and there will be some required properties for each resource  that need to be declared to deploy  a resource, below is the basic syntax to declare a resource

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: Test VPC

Here Resources: is tag under which you need to declare resources that you want deploy and Type:AWS::EC2::VPC is the resource key word for VPC . CidrBlock, EnableDnsHostnames, InstanceTenancy are the basic properties that are needed to create a vpc, and as you can see Intrinsic function !Ref is used to get the value for CidrBlock property by referring to VpcCIDR which is declared in Parameters part.

Intrinsic functions are basically built-in functions that comes within the AWS cloud formation, The intrinsic function Ref returns the value of the given parameter  or resource, when you specify a parameter’s logical name, it returns the value of the parameter and if you specify a resource’s logical name, it returns a value that you can  use to refer to that resource.

Outputs

once the stack is created or the infrastructure is deployed to get the details of resources , for example you have deployed a  ec2 instance and you want Id of that instance you have to go all the way to ec2 dashboard in AWS  web console for this , to make it easier we can declare outputs with in the same template you are using to create your infrastructure , this will give you specific details in the output section of cloud formation, lets see this while creating the stack in CF.
below is the basic syntax to declare a output ,

Outputs:
  Logical ID:
    Description: Information about the value
    Value: Value to return
    Export:
      Name: Name of resource to export

Intrinsic Function in AWS Cloud Formation

Before going on to create whole template to create a VPC Let’s look in to two more intrinsic functions.

!Sub
The intrinsic function  Fn: :Sub called as substitute function substitutes variables in an input string with values that you specify, you can use this function to construct commands or outputs in your template, go through the below given yaml configuration and explanation below it.

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: Test VPC
Outputs:
  VPC:
    Description: VPC ID
    Export:
      Name: !Sub ${AWS::StackName}-VPC
    Value: !Ref VPC

In the  above cloud formation template, Fn:: Sub is used in the output to give a export name, ${Variable name }  this is the syntax to describe a variable using substitute function, !Sub ${AWS::StackName}  is used it to get the stack name and giving it as a Export name.

GetAZs

The intrinsic function Fn::GetAZs returns an array that lists Availability Zones in a region in alphabetical order, so that way you don’t have to hard-code a full list of Availability Zones for a specified region.

Select intrinsic function select  returns a single object from a list of objects based on given index.

Cloud Formation Template to Create  VPC

Below is the complete configuration in yaml for creating a VPC(CIDR: 10.0.0.0/16 ) with one public (CIDR: 10.0.0.0/24) and one private subnet(CIDR: 10.0.1.0/24), go through each block and save in a yaml file.

AWSTemplateFormatVersion: 2010-09-09

Description: This template creates vpc with public and private subnets

# Parameters are used to to build flexible/reusable CloudFormation templates
Parameters:
  VpcCIDR:
    Default: 10.0.0.0/16
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String

  PublicSubnet1CIDR:
    Default: 10.0.0.0/24
    Description: Please enter the IP range (CIDR notation) for the public subnet 1
    Type: String

  PrivateSubnet1CIDR:
    Default: 10.0.2.0/24
    Description: Please enter the IP range (CIDR notation) for the private subnet 1
    Type: String

  SSHLocation:
    Default: 0.0.0.0/0
    Description: The IP address range that can be used to access the web server using SSH.
    MaxLength: '18'
    MinLength: '9'
    Type: String

Resources:
# Create VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: Test VPC

# Create Internet Gateway
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: Test IGW

# Attach Internet Gateway to VPC
  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

# Create Public Subnet1
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      CidrBlock: !Ref PublicSubnet1CIDR
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: Public Subnet 1
      VpcId: !Ref VPC

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

# Add a Public Route to the Route Table
  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref PublicRouteTable

# Associate Public Subnet1 with Public Route Table
  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet1

# Create Private Subnet1
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 0, !GetAZs  '' ]
      CidrBlock: !Ref PrivateSubnet1CIDR
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: Private Subnet 1 | App Tier
      VpcId: !Ref VPC

# Create Security Group for the Web Server
  WebServerSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: Enable traffic on ports 80/http, 443/https, 22/SSH
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: "0.0.0.0/0"
        - IpProtocol: tcp
          FromPort: '443'
          ToPort: '443'
          CidrIp: "0.0.0.0/0"
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: "0.0.0.0/0"
      Tags:
        - Key: Name
          Value: WebServer Security Group
      VpcId: !Ref VPC

#Create an EC2 instance in public subnet.
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: "ami-051dfed8f67f095f5"
      KeyName: key9
      NetworkInterfaces:
        - DeviceIndex: 0
          AssociatePublicIpAddress: true
          DeleteOnTermination: true
          SubnetId: !Ref PublicSubnet1
          GroupSet: 
            - !Ref WebServerSecurityGroup

Outputs:
# Export VPC ID
  VPC:
    Description: VPC ID
    Export:
      Name: !Sub ${AWS::StackName}-VPC
    Value: !Ref VPC

# Export Public Subnet 1 
  PublicSubnet1:
    Description: Public Subnet 1 ID
    Export:
      Name: !Sub ${AWS::StackName}-PublicSubnet1
    Value: !Ref PublicSubnet1

# Export Private Subnet 1
  PrivateSubnet1:
    Description: Private Subnet 1 ID
    Export:
      Name: !Sub ${AWS::StackName}-PrivateSubnet1
    Value: !Ref PrivateSubnet1

# Export WebServer Security Group ID
  WebServerSecurityGroup:
    Description: Webserver Security Group ID
    Export:
      Name: !Sub ${AWS::StackName}-WebServerSecurityGroup
    Value: !Ref WebServerSecurityGroup

# Export DataBase Security Group ID
  EC2Instance:
    Description: EC2 Instance  ID
    Export:
      Name: !Sub ${AWS::StackName}-EC2Instance
    Value: !Ref EC2Instance

Steps to Create Infrastructure using Cloud Formation and Configuration Template

On your AWS web console search for Cloud Formation then click on create stack.

Stack: To create resources defined in template you need to create a stack in cloud formation which allows you to manage your resources like delete update or create.

Then in step-2 give a name to your stack and also you change the default values of the parameters that you declared in the configuration template.

In step-3 you can give tags and the IAM role that should be used by CF to create your stack and in Step-4 Review all the details and click on Create Stack , this will redirect you to events page where you can see the progress of the deployment.

Now go to Outputs to see the values that you have exported in the configuration file.

 

Please contact our cloud consultants if you have any cloud infrastructure related issues to be discussed.

Leave a Reply

Your email address will not be published.

*