How to Deploy VPC & EC2 with CloudFormation

https://github.com/Ngwaabanjong/CloudFormation-projects/tree/main/vpc-ec2-deployment

Introduction:

An AWS CloudFormation template is a JSON or YAML formatted text file that describes your AWS infrastructure. 

TEMPLATES:

  • A template is the code definition which defines the resources that will be created.

STACK:

  • A stack is a collection of AWS resources created from a CloudFormation template.

STACKSETS:

  • StackSets extends the functionality of CloudFormation stacks, and enables you to create, update, or delete stacks across multiple AWS accounts and Regions with a single operation.

CHANGE SETS:

  • Change-sets are used to update an existing Stack, it helps to show the new resources that will be added to the Stack and permit you to apply the new changes or delete the change-set.

DRIFT DETECTION:

  • Helps detect any manual modifications that have been made to your Stack and output the status.
What will be done:
  • We will create a basic VPC and its components.
  • We will create a security group.
  • We will create an ec2 instance in the VPC.
  • We will create Change Set, updating our architecture to 3 tier.
Prerequisites:
  • Configure IAM access to AWS.
  • To avoid Syntax issues, you could copy the code from the GitHub repo, link above.
  • To make it simple I will decouple the infrastructure but the template.yml file in GitHub will have the complete code.
0 – FORMAT VERSION:
  • Optional: but recommended
  • Defines the version of template we are working on
  • “2010-09-09”
AWSTemplateFormatVersion: 2010-09-09
1 – DESCRIPTION:
  • Optional
  • It helps to describe the resources or the workload.
Description: >-
  What this template deploy. 
  It launches a VPC with public and private subnets, 
  a web server EC2 instance in the public subnet 
  and a security group attached to this EC2 instance.
2 – METADATA:
  • Optional
  • It is use to place JSON or YAML objects that provide additional details about the template.
  • Some CloudFormation features use this section to retrieve settings. For example, “AWS::CloudFormation::Interface” key for ordering and grouping parameters.
  • The metadata uses parameter groups to label parameters per resource.
  • After setting parameter groups you need to set parameter labels for certain resources like subnets.
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - 
        Label:
          default: Web Server Settings
        Parameters:
          - InstanceType
          - EbsVolumeSize
          - KeyPairName
      - 
        Label:
          default: VPC Settings
        Parameters:
          - VpcCidrBlocks
          - SubnetAZ
3 – PARAMETERS:
  • Optional
  • It is used to pass values in runtime, while creating and updating stacks.
  • Increase reusability of the template.
  • Parameters can be referenced from “Resources” and “Outputs” sections.
  • Parameters uses Type to define the value type.
  • Different type of values are, String, Number, CommaDelimitedList, Resource Types, etc…
Parameters:
    EnvironmentName:
    Type: String
    Default: Ignatius-lab
    
  InstanceType:
    Type: String 
    AllowedValues:
      - t2.nano
      - t2.micro 
      - t2.small
    Default: t2.micro
  EbsVolumeSize:
    Type: Number
    Description: Volume size in GiB
    Default: 10
  KeyPairName:
    Type: AWS::EC2::KeyPair::KeyName 
  VpcCidrBlocks:
    Type: CommaDelimitedList
    Description: 'vpc, public subnet, private subnet'
    Default: '10.0.0.0/16, 10.0.1.0/24, 10.0.2.0/24'
  SubnetAZ:
    Type: AWS::EC2::AvailabilityZone::Name 
4 – MAPPINGS:
  • Mappings (optional).
  • A mapping of keys and associated values that you can use to specify conditional parameter values, similar to a lookup table.
  • You can match a key to a corresponding value by using the Fn::FindInMap intrinsic function in the Resources and Outputs sections.
Mappings:
  RegionImages:
    eu-west-1:
      ImageId: ami-07683a44e80cd32c5
    us-east-1:
      ImageId: ami-0de53d8956e8dcf80
5 – RESOURCES:
  • Only required section.
  • It is used to define AWS resources and their properties launch by the template.
  • I will decouple this VPC for easy understanding.

5a – VPC:

Resources:
  # vpc 5a ---
  Vpc:
    Type: AWS::EC2::VPC
    Description: Section 5a VPC
    Properties:
      CidrBlock: !Select [ 0, !Ref VpcCidrBlocks ]
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        -
          Key: Name
          Value: !Sub '${AWS::StackName}-vpc'

5b – Subnets:

  # Subnets 5b ---        
  PublicSubnet:
    Type: AWS::EC2::Subnet 
    Properties:
      AvailabilityZone: !Ref SubnetAZ
      CidrBlock: !Select [ 1, !Ref VpcCidrBlocks ]
      MapPublicIpOnLaunch: true
      VpcId: !Ref Vpc
      Tags:
        -
          Key: Name
          Value: !Sub '${AWS::StackName}-public-sub-01'

  PrivateSubnet:
    Type: AWS::EC2::Subnet 
    Properties:
      AvailabilityZone: !Ref SubnetAZ
      CidrBlock: !Select [ 2, !Ref VpcCidrBlocks ]
      VpcId: !Ref Vpc
      Tags:
        -
          Key: Name
          Value: !Sub '${AWS::StackName}-private-sub-01'

5c – Route Tables:

  # Route tables 5c ---
  PublicRouteTable:
    Type: AWS::EC2::RouteTable 
    Properties:
      VpcId: !Ref Vpc
      Tags:
        -
          Key: Name
          Value: !Sub '${AWS::StackName}-public-rt'
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable 
    Properties:
      VpcId: !Ref Vpc
      Tags:
        -
          Key: Name
          Value: !Sub '${AWS::StackName}-private-rt'

5d – Internet Gateway:

  # Internet route for the public route table 5d ---
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
         -
           Key: Name
           Value: !Sub '${AWS::StackName}-internet-gw'
  VpcGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref Vpc
      InternetGatewayId: !Ref InternetGateway
  InternetRoute:
    Type: AWS::EC2::Route
    DependsOn:
      - VpcGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      GatewayId: !Ref InternetGateway
      DestinationCidrBlock: 0.0.0.0/0

5e – Subnets Associations:

  # Subnet - Route table associations 5e ---    
  PublicSubnetRouteTableAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet
  PrivateSubnetRouteTableAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      SubnetId: !Ref PrivateSubnet

5f – Configure EC2 Instance:

  • Create a .pem key pair in your EC2 Console and download the private key.
  • You will select the key pair during deployment.
  # Web server  5f ---
  WebServerInstance:
    Type: AWS::EC2::Instance 
    DependsOn:
      - InternetRoute
      - PublicSubnetRouteTableAssoc
    Properties:
      InstanceType: !Ref InstanceType 
      SubnetId: !Ref PublicSubnet 
      ImageId: !FindInMap [ RegionImages, !Ref 'AWS::Region', ImageId ]
      KeyName: !Ref KeyPairName 
      SecurityGroupIds:
        - !Ref WebServerSecurityGroup
      BlockDeviceMappings:
        - 
          DeviceName: /dev/sdf
          Ebs:
            VolumeSize: !Ref EbsVolumeSize
            VolumeType: gp2
      Tags:
        -
          Key: Name
          Value: !Sub '${AWS::StackName}-web-server'

5g – Create a Security Group for our instance:

  • We need a security group to control traffic to our ec2 instance.
  • We will open port 80 for http and 22 for SSH.
  # security group 5g ---
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup 
    Properties:
      GroupDescription: Activity security group 
      VpcId: !Ref Vpc
      SecurityGroupIngress:
              
        # HTTP rule
        -
          CidrIp: 0.0.0.0/0 
          IpProtocol: tcp
          FromPort: 80
          ToPort: 80

        # SSH rule
        -
          CidrIp: 0.0.0.0/0 
          IpProtocol: tcp
          FromPort: 22 
          ToPort: 22
      Tags:
        -
          Key: Name
          Value: !Sub '${AWS::StackName}-security-group'
6 – OUTPUTS:
  • Optional.
  • It is used to define output values for a stack, for instance DNS hostname of an ELB
  • Outputs can be viewed on AWS Management Console or in the response of AWS CLI calls.
  • In advance level, they can be used to create cross-stack references and pass values between nested stacks.
  # output 
Outputs:
  InstanceID:
    Description: The Instance ID
    Value: !Ref WebServerInstance
  SecurityGrpID:
    Description: The Security group ID
    Value: !Ref WebServerSecurityGroup
  VpcId:
    Description: The ID of the VPC that this stack is deployed in
    Value: !Ref Vpc
    Export:
      Name: !Sub ${EnvironmentName}:VpcId
  PublicSubnetID:
    Description: Public subnet one
    Value: !Ref PublicSubnet
    Export:
      Name: !Sub ${EnvironmentName}:PublicSubnetOne
  PrivateSubnetID:
    Description: Public subnet two
    Value: !Ref PrivateSubnet
    Export:
      Name: !Sub ${EnvironmentName}:PublicSubnetTwo
Deployment Steps:
  • Login to AWS Console.
  • Search AWS CloudFormation.
  • Select: Create Stack -> With new resources (Standard)
  • Select: Template is ready -> Upload a template file -> select: the downloaded template.yml file -> Next.
  • Give a name to your stack -> select key pair and subnet -> Next till create.

Change Set:

  • We will use the change-set.yml file in the github repository.
  • This file is an update of the template.yml file to a 3 tier architecture.

Steps to create Change-sets:

  • On AWS CloudFormation.
  • Select: The existing Stack -> Action -> Create Change set.
  • Select: Replace template -> Upload a template file -> select: the downloaded change-set.yml file -> Next.
  • Select: AZ -> Select: Subnet CIDR -> Next till create.
  • View change set resources that will be added to the Stack, then apply.
Delete Stack.
  • If Stack is not deleted, charges may apply.
  • Click stack and select delete.

**************************************************************************************************

BELOW – this sections were not used on this template.
CONDITIONS:
  • Optional
  • It used to define the statements which describes conditions under a resource can be created or configured.
  • The conditions evaluate to true or false based on the values of these input on the parameters.
TRANSFORM:
  • OPTIONAL
  • AWS Serverless Application Model (SAM) is model based on AWS CloudFormation and used to define serverless applications on AWS.
  • Transform sections is used to specify the AWS SAM version used.

1 thought on “How to Deploy VPC & EC2 with CloudFormation”

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top
%d bloggers like this: