Deploying a Highly Available website with #AWS CloudFormation #incloudbyrk

Master raj
7 min readMar 29, 2024

--

Introduction: In this tutorial, we’ll walk through the process of deploying a highly available simple website infrastructure on AWS using CloudFormation. We’ll leverage AWS services such as EC2, VPC, Elastic Load Balancing, and Auto Scaling to ensure our website remains scalable, resilient, and cost-effective.

Scenario:

Automation and continuous delivery are an integral part of modern infrastructure and application deployments in the cloud. As an aspiring cloud architect, its essential to be skilled in automating infrastructure and constructing continuous delivery pathways for the public cloud. This exercise will see you construct cloud infrastructure and continuous delivery mechanisms utilizing native and non-native IaC methodologies.

AWS:

Architecture Automation

Tasks:

· Deploy a CloudFormation script of the architecture used to deploy the dynamic application from Lab 2 with the following addition, adjustments, and considerations.

Pre-Deployment

  • Create a placeholder Launch Template for automating your ASG (Auto Scaling Group) deployment. (what it’s based-on matter not as this will change post deployment)

So above pateltemplate is the pre-deployement template where you define name , AMI image and Key dont define VPC ,SG or any other detials that we will pass via our IAC script below.

NOTE: SO don`t select any network settings keep it default

Now when u create a template Take a note of launch template ID which you can see above it starts from “lt-xxxxxx___x” and Ami ID “ami-0748249a1ffd1b4d2” also note the type of instance “t2.micro”

Script Deployment

  • Multiple Public subnets
  • Multiple Private subnets
  • IG and NAT-G
  • Security Groups
  • Application Load Balancer and Target Group
  • Auto Scaling Group (Launch Template Required)
  • Read the launch template as a parameter in CloudFormation.
  • EC2 Instance installed within a public subnet.
  • Install with apache, php and basic index.php site.
Parameters:
LaunchTemplateId:
Type: String
Description: The ID of the Launch Template
Default: lt-08a279a0b8061000c #Change this ID according to your ID

Resources:
MyVPC:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: assign2-vpc

PublicSubnet1:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.0.0/24
MapPublicIpOnLaunch: true
AvailabilityZone: ca-central-1a #chnage this region According to region your infrastructure in
Tags:
- Key: Name
Value: PublicSubnet1
PublicSubnet2:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.2.0/24
MapPublicIpOnLaunch: true
AvailabilityZone: ca-central-1b
Tags:
- Key: Name
Value: PublicSubnet2
PrivateSubnet1:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: ca-central-1a
Tags:
- Key: Name
Value: PrivateSubnet1
PrivateSubnet2:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.3.0/24
AvailabilityZone: ca-central-1b
Tags:
- Key: Name
Value: PrivateSubnet2

PublicRouteTable:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: PublicRouteTable

PrivateRouteTable:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: PrivateRouteTable

PublicRoute:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway

PrivateRoute:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway

PublicSubnet1RouteTableAssociation:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable

PublicSubnet2RouteTableAssociation:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable

PrivateSubnet1RouteTableAssociation:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref PrivateSubnet1
RouteTableId: !Ref PrivateRouteTable
PrivateSubnet2RouteTableAssociation:

Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref PrivateRouteTable

InternetGateway:
Type: 'AWS::EC2::InternetGateway'

AttachGateway:
Type: 'AWS::EC2::VPCGatewayAttachment'
Properties:
VpcId: !Ref MyVPC
InternetGatewayId: !Ref InternetGateway

EIP:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
NatGateway:
Type: 'AWS::EC2::NatGateway'
Properties:
AllocationId: !GetAtt EIP.AllocationId
SubnetId: !Ref PublicSubnet1

ALBSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Security group for ALB
VpcId: !Ref MyVPC
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
Tags:
- Key: Name
Value: ALBSecurityGroup
EC2SecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Security group for EC2
VpcId: !Ref MyVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !GetAtt ALBSecurityGroup.GroupId
Tags:
- Key: Name
Value: EC2SecurityGroup



MyLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
SecurityGroups:
- !Ref ALBSecurityGroup
Scheme: internet-facing
Type: application
Tags:
- Key: Name
Value: myALB

MyTargetGroup:
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
Properties:
Port: 80
Protocol: HTTP
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: MyTargetGroup
Targets:
- Id: !Ref MyInstance



MyListener:
Type: 'AWS::ElasticLoadBalancingV2::Listener'
Properties:
LoadBalancerArn: !Ref MyLoadBalancer
Port: 80
Protocol: HTTP
DefaultActions:
- Type: forward
TargetGroupArn: !Ref MyTargetGroup

AutoScalingGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
MinSize: '1'
MaxSize: '3'
DesiredCapacity: '1'
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplateId
Version: '1'
VPCZoneIdentifier:
- !Ref PublicSubnet1
- !Ref PublicSubnet2

MyInstance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: ami-0748249a1ffd1b4d2 #change this AMI ID which noted Above
InstanceType: t2.micro #change this Type According to your instance type
SubnetId: !Ref PublicSubnet1
SecurityGroupIds:
- !Ref EC2SecurityGroup
UserData:
Fn::Base64: |
#!/bin/bash
sudo yum update -y
sudo yum install -y httpd php
sudo systemctl start httpd
sudo systemctl enable httpd
echo "<?php
echo '<h1>Welcome to raj patel website</h1>';
?>" > /var/www/html/index.php

Now go to cloudformation upload your Script:

If you have done everything right creation should complete

other wise it will rollback like other options in screenshot above Make sure you dont change default option while creating cloud formation so that if anything goes wrong everything rollback and wont keep half created resources.

And if you have done everything right Go to Load balancer copy DNS in browser you will see output like this.

You will see output like this congrats you did it

Now second part creating AMI from our launched EC2 instance and replacing ASG template with our customised AMI launched template.

Post-Deployment

Make an AMI from your script deployed EC2 instance.

Creating an AMI from your EC2 Instance:

  1. Navigate to EC2 Dashboard: Go to the EC2 service in the AWS Management Console.
  2. Select the Running Instance: Choose the instance you want to create an AMI from.
  3. Stop the Instance (if necessary): If the instance is running, stop it.
  4. Create Image (AMI): Right-click on the instance, select “Image and templates”, then “Create image”.
  5. Provide Image Details: Enter a name and description for the AMI, along with any additional settings.
  6. Create the Image: Click “Create image” to start the process.
  7. Monitor the Progress: Check the AMIs section for progress. It may take a few minutes.
  8. Accessing the AMI: Once created, find the AMI in the AMIs section of the EC2 dashboard.

now when you try to create launch template in selecting AMI option select my AMI as shown above you will see you newly created AMI in drop down. now you have new launch template which you can see below Assign2temp that is created using customised AMI.

  • Update ASG to use the new launch template.

Now we will change our ASG template which you will see pateltemplate as of now lets change this to Assign2temp and you will notice that after changing as well your website will be running.

  • Verify site is running from ALB DNS

And finally you are done with cloudformation you have created your own AMI hosted the website changed the customised AMI launched template.

Overview: We’ll use AWS CloudFormation to define our infrastructure as code, allowing us to provision and manage resources in a predictable and repeatable manner. Our architecture will include:

  1. Virtual Private Cloud (VPC): To isolate our resources and provide network-level security.
  2. Subnets: Public subnets for resources accessible from the internet and private subnets for backend services.
  3. Internet Gateway: To allow outbound internet access from public subnets.
  4. NAT Gateway: To enable internet access for resources in private subnets.
  5. Application Load Balancer (ALB): To distribute incoming traffic across multiple EC2 instances.
  6. Auto Scaling Group: To automatically adjust the number of EC2 instances based on traffic load.
  7. Security Groups: To control inbound and outbound traffic to our resources.
  8. EC2 Instances: Hosting our simple website application, configured with Apache HTTP server and PHP.

In our blog journey, we began by crafting an Infrastructure as Code (IaC) script, deploying it to launch an EC2 instance using a predefined template. After customizing our instance, we created a bespoke Amazon Machine Image (AMI) to capture its state. Finally, we seamlessly integrated the new AMI into our Auto Scaling Group (ASG), ensuring a scalable and resilient infrastructure for our blog.

#azure #gcp #aws #incloudbyrk #soonincloud

— — — — — — — — — — — — — — — The End — — — — — — — — — — — — —

If you enjoyed reading this blog, please share it with your friends and make sure to subscribe to our YouTube channel for more exciting content. Help us spread the word about our expertise in MERN stack development, cloud computing, React Native, and Next.js, and stay tuned for more informative articles to come. Together, we can take the tech world by storm!

In the Mern Stack Projects section you can find tutorials, tips, cheat sheets, and other projects. Our talks also focus on React Frameworks like NextJs,AWS Cloud So join us today to keep up with the latest technology🩷

📠 🏅:- Mern Stack Projects

🎦 🥇:- Jara diary — YouTube 🚦

🎦 🥈 :- Errormania — YouTube 🚦

On GITHUB :- raj-28 (Raj) (github.com)

💌 Do Subscribe To Our Mailing List To stay Updated With All New Blogs 👍

…………🚦…🛣… ……………🚧🛑………………..▶……………….️

Use Emojis From Here In Case You Need Any….🚦🛣️🥇🥈🥉🏅🎖️🎦👍

--

--

Master raj

Certified MERN Stack Developer from Infosys, now sharing expertise on #InCloudByRK. Proficient in MERN Stack, AWS, GCP, Azure DevOps. Let's level up!