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.
Awesome work Ignatius