Elastic Load Balancing (ELB)
Introduction
Section titled “Introduction”Elastic Load Balancing (ELB) is a service that allows users to distribute incoming traffic across multiple targets, such as EC2 instances, containers, IP addresses, and lambda functions and automatically scales its request handling capacity in response to incoming traffic. It also monitors the health of its registered targets and ensures that it routes traffic only to healthy targets. You can check the official AWS documentation to understand the basic terms and concepts used in the ELB.
Localstack allows you to use the Elastic Load Balancing APIs in your local environment to create, edit, and view load balancers, target groups, listeners, and rules. The supported APIs are available on the API coverage section for ELBv1 and ELBv2, which provides information on the extent of ELB’s integration with LocalStack.
Getting started
Section titled “Getting started”This guide is designed for users new to Elastic Load Balancing and assumes basic knowledge of the AWS CLI and our awslocal wrapper script.
Start your LocalStack container using your preferred method. We will demonstrate how to create an Application Load Balancer, along with its target group, listener, and rule, and forward requests to an IP target.
Start a target server
Section titled “Start a target server”Launch an HTTP server which will serve as the target for our load balancer.
docker run --rm -itd -p 5678:80 ealen/echo-serverCreate a load balancer
Section titled “Create a load balancer”To specify the subnet and VPC in which the load balancer will be created, you can use the DescribeSubnets API to retrieve the subnet ID and VPC ID.
In this example, we will use the subnet and VPC in the us-east-1f availability zone.
subnet_info=$(awslocal ec2 describe-subnets --filters Name=availability-zone,Values=us-east-1f \ | jq -r '.Subnets[] | select(.AvailabilityZone == "us-east-1f") | {SubnetId: .SubnetId, VpcId: .VpcId}')
subnet_id=$(echo $subnet_info | jq -r '.SubnetId')
vpc_id=$(echo $subnet_info | jq -r '.VpcId')To create a load balancer, you can use the CreateLoadBalancer API.
The following command creates an Application Load Balancer named example-lb:
loadBalancer=$(awslocal elbv2 create-load-balancer --name example-lb \ --subnets $subnet_id | jq -r '.LoadBalancers[]|.LoadBalancerArn')Create a target group
Section titled “Create a target group”To create a target group, you can use the CreateTargetGroup API.
The following command creates a target group named example-target-group:
targetGroup=$(awslocal elbv2 create-target-group --name example-target-group \ --protocol HTTP --target-type ip --port 80 --vpc-id $vpc_id \ | jq -r '.TargetGroups[].TargetGroupArn')Register a target
Section titled “Register a target”To register a target, you can use the RegisterTargets API.
The following command registers the target with the target group created in the previous step:
awslocal elbv2 register-targets --targets Id=127.0.0.1,Port=5678,AvailabilityZone=all \ --target-group-arn $targetGroupCreate a listener and a rule
Section titled “Create a listener and a rule”We create a listener for the load balancer using the CreateListener API.
The following command creates a listener for the load balancer created in the previous step:
listenerArn=$(awslocal elbv2 create-listener \ --protocol HTTP \ --port 80 \ --default-actions '{"Type":"forward","TargetGroupArn":"'$targetGroup'","ForwardConfig":{"TargetGroups":[{"TargetGroupArn":"'$targetGroup'","Weight":11}]}}' \ --load-balancer-arn $loadBalancer | jq -r '.Listeners[]|.ListenerArn')To create a rule for the listener, you can use the CreateRule API.
The following command creates a rule for the listener created above:
listenerRule=$(awslocal elbv2 create-rule \ --conditions Field=path-pattern,Values=/ \ --priority 1 \ --actions '{"Type":"forward","TargetGroupArn":"'$targetGroup'","ForwardConfig":{"TargetGroups":[{"TargetGroupArn":"'$targetGroup'","Weight":11}]}}' \ --listener-arn $listenerArn \ | jq -r '.Rules[].RuleArn')Send a request to the load balancer
Section titled “Send a request to the load balancer”Finally, you can issue an HTTP request to the DNSName parameter of CreateLoadBalancer operation, and Port parameter of CreateListener command with the following command:
curl example-lb.elb.localhost.localstack.cloud:4566{ "host": { "hostname": "example-lb.elb.localhost.localstack.cloud", "ip": "::ffff:172.17.0.1", "ips": [] }, "http": { "method": "GET", "baseUrl": "", "originalUrl": "/", "protocol": "http" }, "request": { "params": { "0": "/" }, "query": {}, "cookies": {}, "body": {}, "headers": { "accept-encoding": "identity", "host": "example-lb.elb.localhost.localstack.cloud:4566", "user-agent": "curl/7.88.1", "accept": "*/*" } }, "environment": { "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "HOSTNAME": "bee08b83d633", "TERM": "xterm", "NODE_VERSION": "18.17.1", "YARN_VERSION": "1.22.19", "HOME": "/root" }}Alternative URL structure
Section titled “Alternative URL structure”If a request cannot be made to a subdomain of localhost.localstack.cloud, an alternative URL structure is available, however it is not returned by AWS management API methods.
To make a request against an ELB with id <elb-id>, use the URL:
http(s)://localhost.localstack.cloud:4566/_aws/elb/<elb-id>/<elb-path>Here’s an example of how you would access the load balancer with a name of example-lb with the subdomain-based URL format:
http(s)://example-lb.elb.localhost.localstack.cloud:4566/test/pathWith the alternative URL structure:
http(s)://localhost.localstack.cloud:4566/_aws/elb/example-lb/test/pathMultiple Listeners and Port-Based Routing
Section titled “Multiple Listeners and Port-Based Routing”An Application Load Balancer can have multiple listeners, each bound to a different port. In LocalStack, same-scheme listeners (for example, two HTTP listeners on ports 80 and 8080) are routed by matching the request’s arrival port to the listener’s configured port.
Configuring LocalStack for multiple listener ports
Section titled “Configuring LocalStack for multiple listener ports”To reach two same-scheme listeners on distinct ports, both ports must be published in GATEWAY_LISTEN when starting LocalStack:
GATEWAY_LISTEN=0.0.0.0:4566,0.0.0.0:80,0.0.0.0:8080 localstack startCreating multiple listeners
Section titled “Creating multiple listeners”With LocalStack running and both ports published, create a load balancer and two HTTP listeners on different ports.
The following example uses the subnet_id variable set in the Getting started steps above, and creates two listeners with distinct fixed-response default actions so you can verify that each port routes to the correct listener:
# Create the load balancerloadBalancer=$(awslocal elbv2 create-load-balancer \ --name multi-listener-lb \ --subnets $subnet_id | jq -r '.LoadBalancers[].LoadBalancerArn')
# Listener on port 80awslocal elbv2 create-listener \ --load-balancer-arn $loadBalancer \ --protocol HTTP \ --port 80 \ --default-actions '{"Type":"fixed-response","FixedResponseConfig":{"StatusCode":"200","MessageBody":"Listener 80","ContentType":"text/plain"}}'
# Listener on port 8080awslocal elbv2 create-listener \ --load-balancer-arn $loadBalancer \ --protocol HTTP \ --port 8080 \ --default-actions '{"Type":"fixed-response","FixedResponseConfig":{"StatusCode":"200","MessageBody":"Listener 8080","ContentType":"text/plain"}}'A request to port 80 is handled by the listener bound to that port:
curl multi-listener-lb.elb.localhost.localstack.cloud:80Listener 80A request to port 8080 is handled by the listener bound to that port:
curl multi-listener-lb.elb.localhost.localstack.cloud:8080Listener 8080By-design limitation: shared gateway port
Section titled “By-design limitation: shared gateway port”When a request arrives on the shared :4566 gateway port, LocalStack cannot determine which same-scheme listener was intended and falls back to the first-created listener:
curl multi-listener-lb.elb.localhost.localstack.cloud:4566Listener 80Examples
Section titled “Examples”The following code snippets and sample applications provide practical examples of how to use ELB in LocalStack for various use cases:
Current Limitations
Section titled “Current Limitations”- The Application Load Balancer currently supports only the
forward,redirectandfixed-responseaction types. - When opting for Route53 CNAMEs to direct requests towards the ALBs, it’s important to remember that explicit configuration of the
Hostheader to match the resource record might be necessary while making calls.
API Coverage (ELBv1)
Section titled “API Coverage (ELBv1)”| Operation ▲ | Implemented ▼ | Verified on Kubernetes |
|---|
API Coverage (ELBv2)
Section titled “API Coverage (ELBv2)”| Operation ▲ | Implemented ▼ | Verified on Kubernetes |
|---|