Our nonprod environments have quite a lot Elastic Beanstalk environments. Most of them serves low traffics .Each ELB roughly costs $20 per month (no matter you use it or not) + data cost. From the cost perspective, I don’t see there is a value that each of them needs a dedicated ELB (which was created by Elastic Beanstalk by default).
So I came up an idea to consolidate all those low traffic ELB into one, which saves us a couple of hundred dollars each month easily. But it comes with some trade off as well which does not bother us that much.
- The colour does not reflect the real health status. (We don’t depend on the health status, we check the real URL instead)
- The version label does not reflect the real version#. (We don’t depend the version label, we mark the version# in the site itself)
Here is how I implemented:
- Create a new target group
aws elbv2 create-target-group --name $my-targetgroup --protocol HTTP --port 80 --vpc-id $vpcid
- Find out the auto-scaling group of the EB environment
aws elasticbeanstalk describe-environment-resources --environment-name $my-environment --query 'EnvironmentResources.AutoScalingGroups.Name'
- Attach the auto-scaling group to the target group that is created in step 1.
aws autoscaling attach-load-balancer-target-groups --auto-scaling-group-name $my-asg --target-group-arns $my-targetgroup-arn
- Repeat the above 3 steps for each of the EB environments that you want consolidate the ELB. Then create a new ELB. It is actually ELB V2. AWS calls it either elbv2 or ALB (application load balancer).
aws elbv2 create-load-balancer --name $my-consolidated-load-balancer --subnets $my-subnet1 $my-subnet2 --security-groups $my-sg
- Create DNS CNAME records for your EB environments in Route53, and point them to the new ELB CNAME.
- Now go to the newly created ELB to add hostname based redirect rules, which allows the ELB to divert the traffics to different target group based on the incoming host. Also you need to create a dummy target group which is not associated with any auto-scaling group. And use this dummy target group as the default destination, this will give user 503 if their targeted EB environment is not ready. This is how it looks now.
- Test your new DNS name to confirm it works.
- Find out the ELB that is created by Elastic Beanstalk, then delete it.
aws elasticbeanstalk describe-environment-resources --environment-name $my-environment --query 'EnvironmentResources.LoadBalancers.Name' aws elbv2 delete-load-balancer --load-balancer-arn $my-elb-arn
- In case you may need to restore the ELB, just rebuild the Elastic Beanstalk environment.
- Create a new target group
Updates: To make things simpler and get rid of all the trade offs, you can use ‘Single Instance’ as your environment type. Read my new blog to know how: Hack ‘Environment Type’ in Elastic Beanstalk