AWS offers load balancing to EC2 instances, containers and serverless functions. This enables you to position a fleet of instances to handle incoming requests from the internet.
In a traditional datacenter operation, load balancers distribute traffic onto your virtual machines. AWS's load balancers do the same exact operation but interacts with resources and services in AWS.
This tutorial will show you how to setup an autoscaling group behind a layer 7 application load balancer (ALB).

Prerequisite
For this tutorial, I'm picking up where I left off in my previous post. For you keen-eyed, viewers you may have noticed that there was no way to access the website with your browser.
Now I'm here to let you know that it was totally done on purpose for this post. ;)
If you have torn down the previous environment, you will need to kick off the pipeline in the previous blog post again to recreate the stack. However before you kick off the build again. Let's make some changes to the code.
Open the application.py
file and add host='0.0.0.0', port=80
in application.run().
from flask import Flask, render_template
application = Flask(__name__)
@application.route('/')
def index():
return render_template('index.html')
@application.route('/status')
def status():
return "green"
if __name__ == '__main__':
application.run(host='0.0.0.0', port=80)
Next open up the prod.yml
and add the following in the launch configuration resource section. This will open port 80 on the instance and install pip and flask package for python.
iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT
amazon-linux-extras install epel -y
yum install python-pip -y
pip install Flask
Example of the prod.yml.
# version 2019.10.04
AWSTemplateFormatVersion: '2010-09-09'
Mappings:
AwsRegionAmi:
us-east-1:
AMI: ami-0b69ea66ff7391e80
us-east-2:
AMI: ami-00c03f7f7f2ec15c3
Resources:
myInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- EC2S3RO
myLaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
LaunchConfigurationName: cf-created-standard-prod
KeyName: cf
SecurityGroups:
- sg-04f9c0c282f0bc8de
InstanceType: t2.micro
ImageId: !FindInMap [AwsRegionAmi, !Ref 'AWS::Region', AMI]
BlockDeviceMappings:
- DeviceName: "/dev/xvda"
Ebs:
VolumeSize: 10
VolumeType: gp2
IamInstanceProfile: !Ref myInstanceProfile
UserData:
Fn::Base64: |
#!/bin/bash
DATE=$(date +%Y-%m-%d)
ARTIFACT=$(aws s3 ls s3://codepipeline-us-east-2-710251686107/hello-kitty-ASG/BuildArtif/ | grep ${DATE} | awk '{print $4}')
yum update -y
yum install epel-release vim lynx tcpdump tmux -y
iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT
amazon-linux-extras install epel -y
yum install python-pip -y
pip install Flask
echo "hello lol12345" > /tmp/lol.txt
mkdir /flask
aws s3 cp s3://codepipeline-us-east-2-710251686107/hello-kitty-ASG/BuildArtif/${ARTIFACT} /flask
unzip /flask/${ARTIFACT} -d /flask
python /flask/application.py &
myASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: myCfAsg-prod
AvailabilityZones:
Fn::GetAZs:
Ref: "AWS::Region"
LaunchConfigurationName: !Ref myLaunchConfig
DesiredCapacity: "2"
MinSize: "1"
MaxSize: "3"
Tags:
- Key: Environment
Value: Prod
PropagateAtLaunch: "true"
- Key: Name
Value: ProdInstance
PropagateAtLaunch: "true"
myS3bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: prods3bucket0021
Creating the Target Group
Now that the stack is up and running, create a new target group, mine is named tg-prod
.

Select and enter the following options.
Port: 80
VPC: Your VPC
Protocol: HTTP
Path: /
Port: traffic port
Healthy threshold: 2
Unhealthy threshold: 3
Timeout: 5
Interval: 10
Success codes: 200-299

Now go into "Auto Scaling Groups", notice in the details tab under "Target Groups" that it's blank. I'll fix this now and add the newly created target group here.

Click on the edit button and add the tg-prod
target group, then click save when you're done.

Navigate back to the "Target Groups" page and you should see in the "Targets" tab for tg-prod
the newly created instances from the autoscaling group automatically set as registered targets.
Notice the status is saying "unused", this will change once the ALB is created.

Creating the Load Balancer
On the sidebar to the left, click on "Load Balancers". In the next page click on "Application Load Balancer"
Give it a name, mine is named alb-prod
and make sure the scheme is set to "internet-facing". For the listeners select the protocol for HTTP and port 80.

Create a new security group for the load balancer. Allow HTTP to be accessible everywhere.

Select the tg-prod
as the target group for the ALB to route traffic to.

As you can see the two instances from the auto-scaling group are already registered.

Once the load balancer is up and running, head back into the security groups.
Edit the security group applied to the launch configuration and only allow HTTP to communicate originating from the load balancer's security group.
This will prevent anyone from directly accessing the the EC2 instances by using their public IP. The website should only be served by using the DNS record of the application load balancer.

Now if you check the target group you will see that the instance status has changed to healthy.
Now go ahead and access the website using the ALB's DNS record. You should be greeted by Hello Kitty!

Now if you ever lose one of the instances the ALB will redirect traffic to a healthy instance while the unhealthy instance is terminated and replaced with a new healthy one.