Scaling Made Simple: Creating a Highly Available Web Server with Cloud Formation and Amazon Load Balancer

Ashish Dwivedi
5 min readJul 4, 2023


Here are some key highlights -

Designing a fault-tolerant architecture: I carefully crafted an architecture that utilized multiple web server instances, distributed across availability zones, to ensure redundancy and fault tolerance. The Amazon Load Balancer played a crucial role in evenly distributing incoming traffic across these instances, further enhancing availability and reliability.

Automating infrastructure deployment with Cloud Formation: By utilizing Cloud Formation, I automated the provisioning and configuration of the web server infrastructure. This not only reduced manual effort but also provided a consistent and reproducible deployment process.

Elastic scalability: The solution implemented dynamic scaling capabilities using the Amazon Load Balancer. It automatically adjusted the number of instances based on the traffic load, allowing the web server to handle increased demand seamlessly.

Ensuring optimal performance: Through careful configuration of the Amazon Load Balancer, I optimized the load balancing algorithm, health checks, and session management. These settings helped maintain high performance and responsiveness of the web server.

Monitoring and logging: Comprehensive monitoring and logging were implemented to gain insights into the web server’s performance, detect anomalies, and troubleshoot issues promptly. This proactive approach contributed to the overall stability and reliability of the system.

Configure a highly available and scalable webserver on a RHEL-9 machine by using Cloud Formation on AWS change or replace the desired value

  1. VPC ID
  2. subent ID
  3. image ID
  4. key name
  5. instance type
  6. Availiblity zone
  7. Now create a stack on Cloud Formation on AWS by Following Steps
    step— 1 :- login to your AWS Account with appropriate privilleges
    step — 2 :- search for Cloud Formation service on AWS
    step — 3 :- Create a new Stack
    step — 4 :- Upload the template on the desired section

After this wait for the stack to be created Now take DNS of your newly configured Loadbalancer and search it on the web you can see the web content.

If you want to Understand More about Script Scroll down :

Let’s go through the CloudFormation script step by step and understand each section in detail:

AWSTemplateFormatVersion: "2010-09-09"

This line specifies the version of the AWS CloudFormation template format being used.


The Resources section is where you define the AWS resources you want to create. It is a container for all the resource definitions in the CloudFormation template.

Type: "AWS::EC2::SecurityGroup"
GroupName: MySecurityGroup
GroupDescription: Allow inbound access to EC2 instances
VpcId: <vpc_id>
- IpProtocol: tcp
FromPort: 22
ToPort: 22
- IpProtocol: tcp
FromPort: 443
ToPort: 443
- IpProtocol: tcp
FromPort: 80
ToPort: 80

This section defines an EC2 security group named MySecurityGroup. It allows inbound access to EC2 instances by specifying the desired inbound rules. The rules in this example allow TCP traffic on ports 22 (SSH), 443 (HTTPS), and 80 (HTTP) from any IP address ( You should replace <vpc_id> with the ID of your desired VPC.

Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
Name: MyLoadBalancer
Scheme: internet-facing
- <Subnet_id-1>
- <Subnet_id-2>
- !Ref MySecurityGroup
Type: application
IpAddressType: ipv4
- Key: Name
Value: MyLoadBalancer

This section defines an Elastic Load Balancer (ELB) named MyLoadBalancer. It is configured to be internet-facing and associated with the specified subnets (<Subnet_id-1> and <Subnet_id-2>). It uses the MySecurityGroup defined earlier as its security group. The ELB type is set to application and the IP address type is IPv4. A tag with key "Name" and value "MyLoadBalancer" is also added to the resource for identification.

Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
Name: MyTargetGroup
Port: 80
Protocol: HTTP
VpcId: <vpc_id>
TargetType: instance
HealthCheckEnabled: true
HealthCheckIntervalSeconds: 30
HealthCheckProtocol: HTTP
HealthCheckPath: /
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 2

This section defines a target group named MyTargetGroup. The target group is responsible for routing traffic to the registered instances. It is configured to listen on port 80 (HTTP) and use the HTTP protocol. The VpcId parameter should be replaced with the ID of your VPC. The target type is set to instance, indicating that the target instances will be EC2 instances. Health checks are enabled with specific intervals and thresholds to determine the health of the instances.

Type: "AWS::AutoScaling::LaunchConfiguration"
LaunchConfigurationName: MyLaunchConfiguration1
ImageId: <image_id>
InstanceType: <instance_type>
KeyName: <key_name>
- !Ref MySecurityGroup
Fn::Base64: |
# following commands are to install and configure the web server on RHEL 9
# Example: Install Apache HTTP Server
yum update -y
yum install -y httpd
systemctl enable httpd
systemctl start httpd
# Adding index.html to be hosted on the internet
echo "This site is Hosted using Cloud Shell with a highly available and scalable infrastructure" > /var/www/html/index.html

This section defines a launch configuration named MyLaunchConfiguration1. It specifies the configuration for the EC2 instances that will be launched. You need to replace <image_id> with the appropriate AMI ID for the desired operating system, <instance_type> with the desired EC2 instance type, and <key_name> with the name of an existing EC2 key pair.

The UserData field contains a script that will be executed when each instance is launched. In this case, the script installs and configures an Apache HTTP Server (assuming RHEL 9). It also creates an index.html file with a simple message that will be hosted on the web server.

Type: "AWS::AutoScaling::AutoScalingGroup"
AutoScalingGroupName: MyAutoScalingGroup
LaunchConfigurationName: !Ref MyLaunchConfiguration
MinSize: 3
MaxSize: 6
DesiredCapacity: 3
- <Subnet_id-1>
- <Subnet_id-2>
- !Ref MyTargetGroup
- Key: Name
Value: MyAutoScalingGroup
PropagateAtLaunch: true
HealthCheckGracePeriod: 300
- OldestInstance
- "ap-south-1a"
- "ap-south-1b"

This section defines an auto scaling group named MyAutoScalingGroup. It specifies the configuration for automatically scaling the number of instances based on certain conditions. The LaunchConfigurationName field references the previously defined launch configuration MyLaunchConfiguration.

The MinSize parameter specifies the minimum number of instances in the auto scaling group, MaxSize specifies the maximum number of instances, and DesiredCapacity specifies the desired number of instances.

The VPCZoneIdentifier parameter specifies the subnets in which the instances will be launched. Replace <Subnet_id-1> and <Subnet_id-2> with the actual subnet IDs.

The TargetGroupARNs parameter references the target group MyTargetGroup created earlier.

Tags can be added to the auto scaling group for identification and management purposes. In this case, a tag with key “Name” and value “MyAutoScalingGroup” is added, and it is set to propagate to the instances launched by the auto scaling group.

Other parameters define health check settings, termination policies, and the desired availability zones for the instances.

Type: "AWS::ElasticLoadBalancingV2::Listener"
LoadBalancerArn: !Ref MyLoadBalancer
Protocol: HTTP
Port: 80
- Type: forward
TargetGroupArn: !Ref MyTargetGroup

This section defines a listener for the load balancer MyLoadBalancer. The listener is responsible for accepting incoming traffic and forwarding it to the target group.

The listener is configured to listen on port 80 (HTTP) and forward the traffic to the target group MyTargetGroup.

That’s a detailed explanation of the provided CloudFormation script. It creates a setup with a security group, load balancer, target group, launch configuration, auto scaling group, and listener to create a scalable and highly available infrastructure for hosting a web application.

Happy Automating………….