Can we use one ALB with AWS ECS Fargate? - amazon-web-services

I am having a bunch of micro services running in AWS ECS fargate with ALB and Route53.Each micro service has an ALB with Route53.
Is there any kind of possibility where I can use only one ALB for all the microservices and route to their respective Route53 paths??
Here, I am not using EKS. Using AWS ECS Fargate.

To server multiple Fargate services from a single ALB, you need to create different target groups (TGs) for them. So, each service will have its own TG, and ALB will forward traffic to respective TGs based on some listener rules.
Since you have Route53, a common choice is to create sub-domains, e.g.: service1.example.com and service2.example.com. You associate them as simple Alias A records with the same ALB.
On the ALB you will have single listener (e.g. HTTP 80), with different rules. For example:
Rule one will be based on Host header equal to service1.example.com, with Action of Forward to TG1.
Rule two will be based on Host header equal to service2.example.com, with Action of Forward to TG2.
Some default rule compulsory (or use 2 as default rule).
And that's it. Any request from the internet directed to service1.example.com will go to your TG1 which is Fragete service1. Same for requests to service2.example.com.

Related

Cheap solution for exposing multiple HTTP services in K8s cluster (AWS EKS)

I'm pretty new to k8s and I'm trying to figure out how to expose to Internet, multiple HTTP services, in cheap manner. Currently I'm using AWS EKS cluster with managed node groups, so the cheap way will be not to provision any kind ELB as it cost. Also I would like those services to be in private subnets so just f.ex only Ingress Resource will be exposed and the nodes will stay private. One load balancer per svc is definitely not an option as it will break down my budget
The options I consider:
Using K8s ingress resources (to be precise: Istio Ingress controller). But the downside of that is, when we creating ingress resource, AWS create Load Balancer for which I will need to pay.
Run node groups in public subnets, and create K8s Services of type NodePort so I could reach service using NodeIP:NodePort (NodePort will be specific for each service). The downside of that I will need to remember all IPs and ports assigned to each service. I can live with one service but when the number increase that will be pretty awful to remember.
At last, without any other option is to create one load balancer with public IP and also create Ingress controller with Istio. So I will reach each services by single DNS name of Load Balancer and I will route to services by request path.
Looking forward to any solution and inputs.
I don't think there is any magic here. Option 1 and 3 are basically one and the same (unless I am missing something). As you pointed out I don't think option 2 is viable for the reasons you call out. You have a number of options to go with. I don't know the Istio ingress (but I assume it will be fine). We often see customers using either the NGINX ingress or the ALB ingress.
All of these options require a Load Balancer.

Communication between two or more instances of an ECS service

I know that with AWS ECS's service-discovery you can make one service talk to the other by using the service.cluster pattern at the url (and service discovery does the rest for you). But I want to know if there is a way of doing one instance of a service talk to other container in the same service on AWS Elastic Container Service.
I have searched for this for a while now and decided to ask here as I wasn't able to find any conclusive ideas on how to make it work.
You need to associate your ECS Service with an Application Load Balancer (ALB) which makes sure ECS will registers the tasks (i.e. one or more containers) with the ALB providing a uniform URL for the services to communicate with each other. ALB support path based routing to multiple Target Groups allowing micro-service style communication between tasks/services.
As per the AWS documentation1, you can use a single ALB for multiple services as ALB provides path-based routing and priority-rules. For further information you can also view this link 2 which explains how path-based routing can be used to forward request to different target groups with different ECS tasks/services.

Single AWS WAF on multiple ALB

My application architecture's allowed traffic flow is as below in AWS.
CompanyInternalSubnets(IS)=>ALB with WAF=>EC2
ALB has security groups which allows only traffic from IS. ALB has WAF which has rules to allow traffic only from IS. EC2 has security group which allows only traffic from ALB's SG.
I want to create multiple replica of same application in AWS. I will create sperate EC2 and ALB. but can i use same WAF and attach it to second ALB or do i need to use separate WAF fur each replica? what is the best practice?
Thanks
use the same WAF across since its a replica and why another one? unless you have a different set of rule

AWS ECS - Deploying two different microservices in a single ECS

I have two microservices that need to be deployed in the same ECS service for efficient resource usage.
Both of them have the same context path so cannot use path-pattern filter in the ALB and ECS doesn't seem to allow multiple ALB's in a single ECS.
Is it possible to have two target groups serving the micro services at different ports ? Or is there any other solution ?
Yes you can have two different Target groups each with a unique Port under the same ALB. I use this construction to support HTTP and HTTPS protocol on the same instance with ALB. Should be the same for ECS
You can definitely have a single ALB serving up two different microservices on different ports of ECS instances. Typically when you're going this far, you might want to look at dynamic port mapping. The ALB still needs a way to decide which target group to go to -- hostname matching, for instance.
What I'm not totally sure I understand is why you want to share an ECS service -- why not put each microservice in its own ECS service and share an ALB instead?
Anyway, both are likely possible. I have several microservices, each with their own ECS service sharing ECS instances and an ALB in a cluster using host name matching on the ALB. If you really want to use a single ECS service, it seems like it would still be possible.

How to expose APIs endpoints from private AWS ALB

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.