Bootstrap FreeKB - Amazon Web Services (AWS) - Getting Started with Application Load Balancer (ALB)
Amazon Web Services (AWS) - Getting Started with Application Load Balancer (ALB)


Let's say you have two or more EC2 instances that are producing web apps. An application load balancer can be used to load balance the requests for the web app.

 

For example, let's say EC2 Instance "a" has public DNS name ec2-100-22-33-44.compute-1.amazonaws.com and is listening for HTTPS connections on port 12345. In this example, https://ec2-100-22-33-44.compute-1.amazonaws.com:12345 returns the app by directly hitting the EC2 instance. Let's configure an Application Load Balancer to load balance the requests for the app.

 

First and foremost, let's create a Target Group that will contain the EC2 instances. A Target Group contains:

  • One or more EC2 instances using the EC2 instances ID
  • One or more EC2 instances via IP address
  • One or more EC2 instances via Lambda
  • One or more Application Load Balancers (in other words, a group of Application Load Balancers)

This assumes you have already configured the aws command line tool. If not, check out my article on Getting Started with the AWS CLI

For example, if using the AWS CLI, the aws ec2 describe-vpcs command can be used to the the ID of the Virtual Private Cloud (VPC) you want the Target Group to be in. 

~]$ aws ec2 describe-vpcs --query 'Vpcs[?CidrBlock==`172.31.0.0/16`]' | grep "VpcId"
        "VpcId": "vpc-123abd654dsf356s1",

 

And then the aws elbv2 create-target-group command can be used to create the Target Group. In this example, since --target-type instance was used, this Target Group will contain one or more EC2 instances.

aws elbv2 create-target-group --name my-target-group --protocol HTTP --port 80 --target-type instance --vpc-id vpc-123abd654dsf356s1

 

At this point, if you were to look at the Target Group in the AWS EC2 console, you would see that the Target Group contains no Targets (which are EC2 Instances in this example) and the Target Group is not associated with a Load Balancer.

 

Likewise, the aws elbv2 describe-target-groups command would show that the Target Group is not associated with a Load Balancer (LoadBalancerArns is an empty list).

~]$ aws elbv2 describe-target-groups
{
    "TargetGroups": [
        {
            "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-target-group/af5707bbd67c69ab",
            "TargetGroupName": "my-target-group",
            "Protocol": "HTTP",
            "Port": 80,
            "VpcId": "vpc-123abd654dsf356s1",
            "HealthCheckProtocol": "HTTP",
            "HealthCheckPort": "traffic-port",
            "HealthCheckEnabled": true,
            "HealthCheckIntervalSeconds": 30,
            "HealthCheckTimeoutSeconds": 5,
            "HealthyThresholdCount": 5,
            "UnhealthyThresholdCount": 2,
            "HealthCheckPath": "/",
            "Matcher": {
                "HttpCode": "200"
            },
            "LoadBalancerArns": [],
            "TargetType": "instance",
            "ProtocolVersion": "HTTP1",
            "IpAddressType": "ipv4"
        }
    ]
}

 

This is basically an empty Target Group that at this point serves no purposes.

Let's register EC2 instances in the Target Group. The aws elbv2 describe-target-groups command can be used to get the Amazon Resource Number (ARN) of the Target Group.

~]$ aws elbv2 describe-target-groups | grep TargetGroupArn
            "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-target-group/af5707bbd67c69ab",

 

This is a good point to expand upon the design here. In this simple walk through, we will be configuring the Application Load Balancer to listen on HTTP port 80 and let's say app "a" on each EC2 instance is listening on port 12345 and app "b" in each EC2 instance is listening on port 67890.

 

The aws elbv2 register-targets command can be used to register EC2 instances in the Target Group. Let's just focus on one of the apps in the EC2 instances, app "a" listening on port 12345. The EC2 instances must be up and running to get registered in the Target Group.

aws elbv2 register-targets \
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-target-group/af5707bbd67c69ab \
--targets Id=i-a0908ab089f9008ab,Port=12345 Id=i-c099080ab09dc0909,Port=12345

 

And now you should see both EC2 instances in the Target Group.

 

Now let's create the Application Load Balancer.  The aws elbv2 create-load-balancer command can be used to create the Application Load Balancer. I am not going to get into the details of each option here since this is really meant to be just a simple Getting Started article but I would like to at least mention this.

  • I am using the same subnets as are being used by the two EC2 instances I registered in the Target Group
  • I am using the same Security Group that is being used by the EC2 instances I registered in the Target Group
  • Since I'm going with internet-facing the subnets must be public - check out my article Create Private Subnet (no Internet access) for more details on public vs. private subnets - This will make it easier to do proof of concept, as I'll be able to submit a GET request to the load balancer over the Internet
aws elbv2 create-load-balancer 
--name my-application-load-balancer
--type application
--subnets subnet-03f11411234f6abcd subnet-03123451234f7ab34
--security-groups sg-0c3296123415abcd1
--scheme internal

 

Now if you look at your Application Load Balancer in the AWS EC2 console, you should see the Load Balancer exists and after a few minutes should be Active, but the Load Balancer doesn't have any Listeners, such as HTTP port 80 or HTTPS port 443, so the next thing to do is to create one or more listeners.

 

The aws elbv2 create-listener command can be used to create a Listener, using the Amazon Resource Number (ARN) of the Load Balancer and the ARN of the Target Group.

aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-application-load-balanacer/af699b53c6c024d9 \
--protocol HTTP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-target-group/af5707bbd67c69ab

 

Now over in the AWS EC2 console, the Load Balancer should be configured with a Listener that will forward requests onto the EC2 instances in the Target Group. Getting there!

 

And now if we look at the Targets in the Target Group, we want them to both be Healthy, which means the Application Load Balancer is all full of joy and happy and things should be working properly.

 

And then when I enter the URL of my Application Load Balancer in my web browser, it totally works. The request is forwarded onto one of the EC2 instances in the Target Group and the app listening on port 12345 is returned. How cool!

 

Bonus Points - If you are using AWS Route 53 and you have a Hosted Zone, you can create an A Alias record that points to your Application Load Balancer. For example, I created an A Alias record alb.freekb.link that pointed to my Application Load Balancer.

 

And now I can hit my Application Load Balancer using the A Alias record instead of the DNS name provided by AWS.

 

But remember, we have different apps on the EC2 instances, app "a" listening on port 12345, app "b" listening on port 67890. So how do we load balance between the apps? This is where HTTP Host Header Listener Rule comes into play.

 

Let's create two Target Groups, one for app "a" and the other for app "b".

aws elbv2 create-target-group --name a-target-group --protocol HTTP --port 80 --target-type instance --vpc-id vpc-123abd654dsf356s1

aws elbv2 create-target-group --name b-target-group --protocol HTTP --port 80 --target-type instance --vpc-id vpc-123abd654dsf356s1

 

And register both EC2 instances in a-target-group with port 12345 and register both EC2 instance in b-target-group with port 67890.

aws elbv2 register-targets \
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/a-target-group/af5707bbd67c69ab \
--targets Id=i-a0908ab089f9008ab,Port=67890 Id=i-c099080ab09dc0909,Port=12345

aws elbv2 register-targets \
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/b-target-group/af5707bbd67c69ab \
--targets Id=i-a0908ab089f9008ab,Port=67890 Id=i-c099080ab09dc0909,Port=67890

 

Now let's create 2 HTTP Host Header Listener Rule

  • if HTTP Host Header is a.freekb.link forward the request onto a-target-group
  • if HTTP Host Header is b.freekb.link forward the request onto b-target-group

 

And then create 2 A Alias records. In this example, both a.freekb.link and b.freekb.link forward reqeusts onto the Application Load Balancer.

 

Now when I go to a.freekb.link, the request is routed onto the Application Load Balancer, and then the HTTP Host Header Listener Rules are evaluated, and the Rule containing a.freekb.link is matched and the request get forwarded onto a-target-group, returning app "a".

 

Likewise, when I go to b.freekb.link, the request is routed onto the Application Load Balancer, and then the HTTP Host Header Listener Rules are evaluated, and the Rule containing b.freekb.link is matched and the request get forwarded onto b-target-group, returning app "b". How cool!

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 155894 in the box below so that we can be sure you are a human.