My applications run on ElasticBeanstalk and communicate purely with internal services like Kinesis and DynamoDB. There is no web traffic needed? Do I need an ElasticLoadBalancer in order to scale my instances up and down. I want to add and remove instances purely based on some cloudwatch metrics? Do I need the ELB to do managed updates etc.?
If there is no traffic to the service then there is no need to have a load balancer.
In fact the load balancer is primarily to distribute inbound traffic such as web requests.
Autoscaling can still be accomplished without a load balancer with scaling based on the CloudWatch metric that you want to use. In fact this is generally how consumer based applications tend to work.
To create this without a load balancer you would want to configure you environment as a worker environment.
#Chris already anwsered, but I would like to complement his answer for the following:
There is no web traffic needed?
Even if you communicate with Kinesis and DynamoDB only, your instances still need to be able to access internet to communicate with the AWS services. So the web traffic is required from your instances. The direct inbound traffic to your instances is not needed.
To fully separate your EB env from the internet you should have a look at the following:
Using Elastic Beanstalk with Amazon VPC
The document describes what you can do and want can't be done when using private subnets.
Related
I have an on-premises load balancer that I wish to use to distribute traffic on EC2s in an Autoscaling group(ASG).
When AWS's Elastic Load Balancer(ELB) registers an ASG as a target, during a scale-out,new instances are automatically registered to ELB to route traffic to.
Can the same functionality be achieved in any way with an on-prem load balancer?
There is in-built integration between Amazon EC2 Auto-Scaling and Elastic Load Balancers. The Auto Scaling systems knows how to modify Target Groups to add/remove instances. However, it has no knowledge about your on-premises load balancer.
You could use Amazon EC2 Auto Scaling lifecycle hooks to trigger additional code (that you write) to add/remove the instances to your own load balancer, but that would require an AWS Lambda function to communicate with the on-premises load balancer to update the configuration.
If you wanted to get the IPs of your target group you can do that do with an API call, and put that into your LB, but I think you may as well proxy calls from your LB to an ELB sitting on AWS which does the actual LoadBalancing. IMO there is way too much work and a lot could go wrong if you were to try and re-implement ELB features using Lambda functions.
I was going through the article https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance#how-different-is-eureka-from-aws-elb about Eureka when I came across this term. Also quite confused what the paragraph means (EC2 classic and AWS security groups). It said
AWS Elastic Load Balancer is a load balancing solution for edge services exposed to end-user web traffic. Eureka fills the need for mid-tier load balancing. While you can theoretically put your mid-tier services behind the AWS ELB, in EC2 classic you expose them to the outside world and thereby losing all the usefulness of the AWS security groups.
I'm completely new to Microservice architecture and reading articles from sources I can find. Any help would be helpful!
A mid-tier load balancer is a load balancer that isn't exposed to the Internet, but instead is intended to distribute internally-generated traffic between components in your stack.
An example would be the "order placement" (micro)service verifying prices by sending requests to the "catalog item details" (micro)service -- you need a mid-tier load balancer in front of the multiple nodes providing the "catalog item details" service so that the request is routed to a healthy endpoint for that service, without "order placement" needing to be responsible for somehow finding a healthy "catalog item details" endpoint on its own.
Eureka was first committed to Github in 2012. Back then, much of EC2 was still running inside "EC2 Classic" -- in simple terms, this is the old way EC2 worked, before VPC. It was a much more primitive environment compared to today.
With EC2-Classic, your instances run in a single, flat network that you share with other customers. With Amazon VPC, your instances run in a virtual private cloud (VPC) that's logically isolated to your AWS account.
The EC2-Classic platform was introduced in the original release of Amazon EC2. If you created your AWS account after 2013-12-04, it does not support EC2-Classic, so you must launch your Amazon EC2 instances in a VPC.
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-classic-platform.html
EC2 Classic supported security groups for securing access to EC2 instances, but Elastic Load Balancers (ELB) inside EC2 Classic did not.
VPC became generally available in August, 2011.
Elastic Load Balancer -- originally the only type, this type was later rebranded as "ELB Classic," and is not recommended for new environments -- was released for VPC in November, 2011 but only in the Internet-facing variety. Before this, as noted above, ELB only worked in EC2 Classic, only faced the Internet, and accepted HTTP and HTTPS traffic from everywhere. You couldn't control access with security groups.
ELB Classic learned a new trick in June 2012, with the release of Internal Elastic Load Balancers -- accessible only from services inside the VPC. These could be used securely for mid-tier, but they were very limited because they could not make routing decisions based on hostname or path. ELB Classic was a very barebones load balancer with very little flexibility. You'd essentially need a different balancer for each service. One commom configuration was to use HAProxy behind ELB Classic to fill in some of the feature gaps.
AWS didn't have a solid, managed, mid-tier load balancer offering until August, 2016, when the new Application Load Balancer was announced -- with the ability to send traffic to different backend target groups based on pattern matching in the request path sent to the balancer... and with support for deploying in an Internet-facing or internal-only scheme.
In April, 2017, Application Load Balancers were enhanced with the ability to also select a back-end target group based on pattern-matching the HTTP Host header and/or the path, as before.
At this point, VPC and ALB fill many (but, in some cases, not all) of the needs that seem to have driven the development of Eureka.
I would assume that this middle tier is something that can act as a barrier or protection against your AWS ELB. Let use examples of people trying to do an SQL injection attack or spamming your AWS ELB. Also, SG in AWS allows you to specify what protocols are coming to the ALB or any other resources in AWS when you create them. So for example, you can set up an SG that only accepts traffic from your middle-tier server as an additional level of security.
Hope this helps with a better understanding.
I have a scenario where I have to deploy multiple micro-services on AWS ECS. I want to make services able to communicate with each other via APIs developed in each micro-service. I want to deploy the front-end on AWS ECS as well that can be accessed publicly and can also communicate with other micro-services deployed on AWS ECS. How can I achieve this? Can I use AWS ECS service discovery by having all services in a private subnet to enable communication between each of them? Can I use Elastic Load Balancer to make front-end micro-service accessible to end-users over the internet only via HTTP/HTTPS protocols while keeping it in a private subnet?
The combination of both AWS load balancer ( for public access) and Amazon ECS Service Discovery ( for internal communication) is the perfect choice for the web application.
Built-in service discovery in ECS is another feature that makes it
easy to develop a dynamic container environment without needing to
manage as many resources outside of your application. ECS and Route 53
combine to provide highly available, fully managed, and secure service
discovery
Service discovery is a technique for getting traffic from one container to another using the containers direct IP address, instead of an intermediary like a load balancer. It is suitable for a variety of use cases:
Private, internal service discovery
Low latency communication between services
Long lived bidirectional connections, such as gRPC.
Yes, you can use AWS ECS service discovery having all services in a private subnet to enable communication between them.
This makes it possible for an ECS service to automatically register
itself with a predictable and friendly DNS name in Amazon Route 53. As
your services scale up or down in response to load or container
health, the Route 53 hosted zone is kept up to date, allowing other
services to lookup where they need to make connections based on the
state of each service.
Yes, you can use Load Balancer to make front-end micro-service accessible to end-users over the internet. You can look into this diagram that shows AWS LB and service discovery for a Web application in ECS.
You can see the backend container which is in private subnet, serve public request through ALB while rest of the container use AWS service discovery.
Amazon ECS Service Discovery
Let’s launch an application with service discovery! First, I’ll create
two task definitions: “flask-backend” and “flask-worker”. Both are
simple AWS Fargate tasks with a single container serving HTTP
requests. I’ll have flask-backend ask worker.corp to do some work and
I’ll return the response as well as the address Route 53 returned for
worker. Something like the code below:
#app.route("/")
namespace = os.getenv("namespace")
worker_host = "worker" + namespace
def backend():
r = requests.get("http://"+worker_host)
worker = socket.gethostbyname(worker_host)
return "Worker Message: {]\nFrom: {}".format(r.content, worker)
Note that in this private architecture there is no public subnet, just a private subnet. Containers inside the subnet can communicate to each other using their internal IP addresses. But they need some way to discover each other’s IP address.
AWS service discovery offers two approaches:
DNS based (Route 53 create and maintains a custom DNS name which
resolves to one or more IP addresses of other containers, for
example, http://nginx.service.production Then other containers can
send traffic to the destination by just opening a connection using
this DNS name)
API based (Containers can query an API to get the list of IP address
targets available, and then open a connection directly to one of the
other container.)
You can read more about AWS service discovery and use cases amazon-ecs-service-discovery and here
According to the documentation, "Amazon ECS does not support registering services into public DNS namespaces"
In other words, when it registers the DNS, it only uses the service's private IP address which would likely be problematic. The DNS for the "public" services would register to the private IP addresses which would only work, for example, if you were on a VPN to the private network, regardless of what your subnet rules were.
I think a better solution is to attach the services to one of two load balancers... one internet facing, and one internal. I think this works more naturally for scaling the services up anyway. Service discovery is cool, but really more for services talking to each other, not for external clients.
I want to deploy the front-end on AWS ECS as well that can be accessed publicly and can also communicate with other micro-services deployed on AWS ECS.
I would use Service Discovery to wire the services internally and the Elastic Load Balancer integration to make them accessible for the public.
The load balancer can do the load balancing on one side and the DNS SRV records can do the load balancing for your APIs internally.
There is a similar question here on Stack Overflow and the answer [1] to it outlines a possible solution using the load balancer and the service discovery integrations in ECS.
Can I use Elastic Load Balancer to make front-end micro-service accessible to end-users over the internet only via HTTP/HTTPS protocols while keeping it in a private subnet?
Yes, the load balancer can register targets in a private subnet.
References
[1] https://stackoverflow.com/a/57137451/10473469
If I have a microservice that does not have http/https endpoints, and its sole purpose is to pull data from an ActiveMQ queue. It is possible to to set up a load balancer that doesn't require a http/https listener on the microservice?
From aws support:
"In this scenario, if you are hosting your services, which are responsible for pulling up data from Active MQ, on EC2 instances, you can make use Auto Scaling with the appropriate scaling policy. This will help you accomplish scaling up and down of the instances according to the load requirement or settings"
This is what I was looking for
We are having several microservices on AWS ECS. We have single ALB which has different target group for different microservices. We want to expose some endpoints externally while some endpoints just for internal communication.
The problem is that if we put our load balancer in public VPC than it means that we are exposing all register endpoints externally. If we move load balancer to private VPC, we have to use some sort of proxy in public VPC, which required additional infra/cost and custom implementation of all security concerns like D-DOS etc.
What possible approaches we can have or does AWS provide some sort of out of the box solution for this ?
I would strongly recommend running 2 albs for this. Sure, it will cost you more (not double because the traffic costs won't be doubled), but it's much more straight forward to have an internal load balancer and an external load balancer. Work hours cost money too! Running 2 albs will be the least admin and probably the cheapest overall.
Checkout WAF. It stands for web application firewall and is available as AWS service. Follow these steps as guidance:
Create a WAF ACL.
Add "String and regex matching" condition for your private endpoints.
Add "IP addresses" condition for your IP list/range that are allowed to access private endpoints.
Create a rule in your ACL to Allow access if both conditions above are met.
Assign ALB to your WAF ACL.
UPDATE:
In this case you have to use external facing ALB in a public subnet as mentioned by Dan Farrell in comment below.
I would suggest doing it like this:
one internal ALB
one target group per microservice, as limited by ECS.
one Network load balancer(NLB), with one ip based target group.
The Ip based target group will have the internal ALB ip addresses,as the private ip addresses for ALB are not static, you will need to setup cloudwatch cron rule with this lambda function(forked from aws documentation and modified to work on public endpoints as well):
https://github.com/talal-shobaita/populate-nlb-tg-withalb/
Both ALB and NLB are scalable and protected from DDOS by AWS, AWS WAF is another great tool that can be attached directly to your ALB listener for extended protection.
Alternatively, you can wait for AWS to support multiple target group registration per service, it is already in their roadmap:
https://github.com/aws/containers-roadmap/issues/104
This how we eventually solved.
Two LB one in private and one in public subnet.
Some APIs meant to be public, so directly exposed through public LB.
For some private APIs endpoints need to be exposed, added a proxy in public LB and routed those particular paths from public LB to private LB through this proxy.
These days API Gateway is the best way to do this. You can have your API serve a number of different endpoints while serving only the public ones via API Gateway and proxying back to the API.
I don't see it mentioned yet so I'll note that we use a CloudMap for internal routing and an ALB for "external" (in our case simply intra/inter-VPC) communication. I didn't read in depth, but I think this article describes it.
AWS Cloud Map is a managed solution that lets you map logical names to the components/resources for an application. It allows applications to discover the resources using one of the AWS SDKs, RESTful API calls, or DNS queries. AWS Cloud Map serves registered resources, which can be Amazon DynamoDB tables, Amazon Simple Queue Service (SQS) queues, any higher-level application services that are built using EC2 instances or ECS tasks, or using a serverless stack.
...
Amazon ECS is tightly integrated with AWS Cloud Map to enable service discovery for compute workloads running in ECS. When you enable service discovery for ECS services, it automatically keeps track of all task instances in AWS Cloud Map.
You want to look at AWS Security Groups.
A security group acts as a virtual firewall for your instance to control inbound and outbound traffic.
For each security group, you add rules that control the inbound traffic to instances, and a separate set of rules that control the outbound traffic.
Even more specific to your use-case though might be their doc on ELB Security Groups. These are, as you may expect, security groups that are applied at the ELB level rather than the Instance level.
Using security groups, you can specify who has access to which endpoints.