AWS Elastic Beanstalk environment with multiple Load Balancers - amazon-web-services

I have the following situation:
I have 1 Rails App that has 2 domains, each of these domains has multiple/dynamical subdomains.
This app is in AWS using a load-balanced Elastic Beanstalk.
What i need is that those 2 domains that points to my single Rails App to work under SSL in port 443.
But since Elastic Beanstalk has only one load balancer, I can only use one single SSL certificate on port 433 :(
Using a UCC SSL certificate won't be the solution because i need each domain certificate to be wildcard, so the dynamic subdomains will also work.
Any thoughts about how to get multiple Load Balancers playing nicely with an Elastic Beanstalk Environment?
Best.

To add multiple Elastic Load Balancers (ELB) to an Elastic Beanstalk (EB) application, you need to add the additional ELB to the auto scaling group of the EB app.
On the command line
The easiest way to achieve this is through the AWS CLI (https://aws.amazon.com/cli/):
aws autoscaling attach-load-balancers --auto-scaling-group-name <SG_NAME> --load-balancer-names <ELB_NAME>
In the AWS Console
Of course this can be done in the AWS Console, too:
Go to EC2 > Auto Scaling > Auto Scaling Groups
select the group you want to add the elb to
Select the Details Tab
Edit-Button on the top right
Use the Autocompletion in the Load Balancers field to add your load balancer
Save
For your convenience, you can see where you need to click for all of the 5 steps (don't forget to save!)
For me this works also on eb-generated auto scaling groups (Region: eu-central-1).
This might not have been available at the time of the question, but it is now.

It's a tough one with Elastic Beanstalk as they have a cookie cutter way of deploying your app and if it's not in their options then you have either "hack it" or just go with a completely different solution using EC2 or plain cloud servers.
One thing you can try is creating another ELB with the certificate of the second domain (and subdomains) and point it to your Elastic Beanstalk Instance. If you go to the ELB console you should be able to see the ELB for the first domain. Then, you can create your second domain based on the first domain.
Hope it helps.

I think that the best solution for your problem is to have multiple domains on the same SSL certificate and then assign that certificate to your ELB environment.
(you can have wildcards, maybe that wasn't available at the time the question was asked)
You don't need extra load balancers.

This worked for me,
First, create the load balancer
aws elb create-load-balancer --load-balancer-name my-load-balancer --listeners "Protocol=HTTP,LoadBalancerPort=80,InstanceProtocol=HTTP,InstancePort=80" "Protocol=HTTPS,LoadBalancerPort=443,InstanceProtocol=HTTP,InstancePort=80,SSLCertificateId=arn-of-certificate" --subnets eb-subnet-of-primary-elb --security-groups sg-of-primary-elb
Then, attach load balancer to primary auto scaling group of EB env
aws autoscaling attach-load-balancers --auto-scaling-group-name asg-name-of-primary-asg-in-eb --load-balancer-names my-load-balancer

One more thing to be aware of is that EBS created instances need to allow your custom ELB to talk to them.
You need to create INBOUND rule in your EBS auto-created security group (with description SecurityGroup for ElasticBeanstalk environment) to allow TCP:80 access. I had my custom ELBs in a different security group so I specified that sg-**** ID as the source.

Related

How does Elastic Beanstalk support multiple EC2 instances for a web server?

Maybe I am not understanding what exactly Elastic Beanstalk should be used for, so my question is this:
How does Elastic Beanstalk have the ability to support multiple EC2 instances in the same Elastic Beanstalk Environment if the instances act as a backend web server?
For example, if I have a server that has the end point www.example.com/api/endpoint, does Elastic Beanstalk allow me to have more than 1 instance (for high availability) with that same endpoint? Is that possible? If not, how do you make use of the extra EC2 instances if they all have different domains?
How do I send requests to the Elastic Beanstalk environment (from a front end web app) that all instances can understand?
You're going to need to watch some video's.
ElasticBeanStalk is for lazy developers who don't want to learn Cloud Technology ;) I know because I was one once!
ElasticBeanStalk creates a VPC that has Subnets by default 1 per Availability Zone (AZ), and the number of AZs depends on the regions number of AZs. The VPC it creates will have a Internet Gateway attached via the Route Tables making it Public.
In the Subnet(s) ElasticBeanStalk will spin up a EC2/VM to host your website.
ElasticBeanStalk will make a Network Security Group (NSG) opening port 80 &/or 443 and because the VPC is public plus the NSG is open the EC2 will be accessible to the WWW.
If you've chosen an Auto Scale Group (ASG) the ASG will spin up/down EC2s depending typically on CPU but you can use CloudWatch metrics.
With an ASG the ElasticBeanStalk will spin up a Elastic Load Balancer (ELB) and that will coordinate the traffic coming into the Internet Gateway to the VMs. The ELB is registered with the ASG and that's how it knows the ASG spun up or down EC2 instances. This is how the ELB can deliver the traffic using either Level4 (a range of IP addresses) or Layer7 (a range of IP Addresses plus HTTP Request, Header & etc info) to the EC2s currently running in a "Target Group".
if I have a server that has the end point www.example.com/api/endpoint, does Elastic Beanstalk allow me to have more than 1 instance (for high availability
Yes! And its actually quite tricky to demonstrate because you hit the same URL and need to get the ID of the different instances in the ASG.
The best resource is Ryan Kroonenberg's A Cloud Guru "Solution Architect Associate" video on VPCs, Chapter 9. https://acloudguru.com/course/aws-certified-solutions-architect-associate-saa-c02-4KYV (you can find an yrs old torrent with it)
This diagram isn't 100% accurate, the ASGs stretch across AZs:

Use a Web Application Firewall (WAF) with an EC2 instance

I have a web app running on my Amazon EC2 instance. How can I integrate a Web Application Firewall with my EC2?
I have tried setting up the WAF, but it can only be associated with either a CloudFront distribution or an Elastic Load Balancer. Do I need to setup a CloudFront distribution and point it at my EC2 instance?
I ended up setting up an elastic load balancer pointing to my single instance and then adding the web application firewall pointing to the load balancer. It works pretty well and doesn't cost too much more per month from AWS.
The two approaches you can connect AWS WAF to your EC2 instance through,
AWS CloudFront
Application Load Balancer (ALB)
Each approach has its own pros and cons. If your application servers more of content that can be cached, then having AWS CloudFront along with WAF. If your application cluster needs to scale but most of it is dynamic content then going for ALB is more reasonable.
Note: There is an added fixed cost for ALB (In addition to the variable cost which is not significant though) for each month while CloudFront cost is variable and consumption driven.
It is also possible to have both CloudFront and ALB together where you can add the WAF to CloudFront only.
This is how you use AWS WAF, it only works in these two scenarios. For an EC2 application it is best to configure an ALB in front of it (even if you have only one instance).
BTW: You might get away with only using the Application Loadbalancer (ALB) from AWS, this is doing more content validity checks than classic AWS ELB is doing.
You need to set up at least Application layer Loadbalancer to use AWS WAF.
side note: AWS WAF has a lot of restriction. For request count based blocking you will end up having LAMBDA scripts to COUNT and update the AWS WAF ruleset. Also, they don't provide WAF logs as of my Knowledge. Try looking at cloud WAF solutions like SOPHOS.

Load balancing across different Elastic Beanstalk applications

In my AWS environment there are some load balanced / autoscaled Elastic Beanstalk applications.
I would like to have a load balancer in front of them, so any request to http://loadbalancer.com/app1 is routed to the first Elastic Beanstalk app, http://loadbalancer.com/app2 to the second and so on.
I tried to set up an application load balancer with different listeners routing to different target groups.
Unfortunately my solution is not ideal, because the target groups are bound to a fixed set of EC2 instances, while I want them to be associated to an environment where instances are created or destroyed on demand
I haven't still found a way of binding an application load balancer's listener to an auto scaling group.
Is there a way of achieving what I want?
I just managed to do it, following the instructions in this article
https://aws.amazon.com/blogs/devops/introducing-application-load-balancer-unlocking-and-optimizing-architectures/
the steps:
1) create a new target group
aws elbv2 create-target-group --name <target_group_name> --protocol HTTP --port 80 --vpc-id <vpc_id>
2) bind your target group to the autoscaling group associated to the app
aws autoscaling attach-load-balancer-target-groups --auto-scaling-group-name <id_of_the_autoscaling_group> --target-group-arns "<new_target_group_arns>"
3) create a new rule in the main application load balancer, that routes the desired path to the right application (this can be done through the UI).
The way I achieved this in the console for Application load balancer and elastic beanstalk is the following
Create new target group (TG-App1)
Attach TG-App1 to your beanstalk environments auto scale group. Now you will have both the beanstalk created target group and TG-App1 attached and both will now update with the instances.
Create new application load balancer (ALB-App)
Create ALB-App rules forwarding to TG-App1 (ex: PATH: /app1/* -> FORWARD: TG-App1)
Update the beanstalk environment instance security group to allow traffic from ALB-App's security group on port 80. (you will have 2 port 80 rules now, 1 for ALB-App and 1 for the default beanstalk load balancer security group)
This allows you to setup dns on ALB-App ("loadbalancer.com") and forward traffic based on rules to different target groups that have instances managed by different beanstalks. Just follow the steps to create a target group for each beanstalk environment and add it to the rules on ALB-App
the result:
"loadbalancer.com/app1" -> ALB-App -> TG-App1 -> Beanstalk Environment 1 instances
"loadbalancer.com/app2" -> ALB-App -> TG-App2 -> Beanstalk Environment 2 instances
Amazon Elastic Beanstalk now support for shared load balancers
11 - Sept-2020
https://aws.amazon.com/blogs/containers/amazon-elastic-beanstalk-introduces-support-shared-load-balancers/

AWS Elastic Beanstalk - add load balancer to app retroactively

I got a new domain and want to change my Elastic Beanstalk app name from domain-name.elasticbeanstalk.com to www.domain-name.com. When I created the EB app, I chose Single Instance.
I followed these instructions to set up the domain. I selected my load balancer, but my domain seems to map to another app I have. This seems to be because I only created one load balancer with another EB app, and not the current app I am trying to map the domain to.
My questions are:
1) How can I use the single load balancer (associated with a different app) to point the domain correctly? This is probably not possible.
2) How can I retroactively add a load balancer to an existing EB app? Or do I have to recreate the EB app and add the Load Balancer at that point?
From the two options you provided, I will suggest to use the second option.
EB = Elastic Beanstalk
ELB = Elastic Load Balancer
Follow the below steps.
Launch a ELB in AWS Console. If your EB instance is in a VPC then launch the ELB in the same VPC.
When you are launching the ELB attach the EB instance to that load balancer.
Then you can point your domain www.domain-name.com to that ELB using Route 53.
Or you can change your environment type from single instance to Load Balancing Environment. In this case, check below user Guide:
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features-managing-env-types.html?icmpid=docs_elasticbeanstalk_console

AWS: How to route to autoscaling group based on URL pattern?

Our app has independent clusters of boxes running on Amazon Web Services. I need to send http requests to different clusters based on the URL. For example, http://api.mydomain.com/foo should go to the "foo" cluster, and http://api.mydomain.com/bar should go to the "bar" cluster.
I don't see anything in the elastic load balancer or Route 53 that will do it.
(The obvious thing is to have separate subdomains, but that's difficult for this app. We want to stick with just the "api" subdomain because the cluster configuration may change in the future.)
What's the best approach?
That is not supported by the load balancer. Using subdomains does work if you want to use the existing load balancer.
If you need more features, you could configure your own using a software load balancer running on top of an ec2 instance. Not likely to be as cost effective however.
It is not possible using ELB. Use Netscaler EC2 or HAProxy EC2 in your AWS environment to achieve this. NetScaler is available in AWS marketplace.