3

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 ?

Rahul Garg
  • 4,069
  • 1
  • 34
  • 31

7 Answers7

1

Checkout WAF. It stands for web application firewall and is available as AWS service. Follow these steps as guidance:

  1. Create a WAF ACL.
  2. Add "String and regex matching" condition for your private endpoints.
  3. Add "IP addresses" condition for your IP list/range that are allowed to access private endpoints.
  4. Create a rule in your ACL to Allow access if both conditions above are met.
  5. 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.

Community
  • 1
  • 1
Victor
  • 474
  • 5
  • 18
  • 3
    Connections to an internal alb will never be on an external endpoint, and requests to an external elb will never be from an external endpoint. So this would only work if you made the alb external. Then you'd also have to allow traffic from external ips, so whatever may gateway your internal traffic exits through – erik258 Feb 12 '18 at 22:46
1

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.

erik258
  • 14,701
  • 2
  • 25
  • 31
  • As per my understanding, one ALB (application load balancer) can't redirect to another ALB. Please correct me if my understanding is not valid. – Rahul Garg Feb 13 '18 at 17:02
  • I think you're right, but I'm not suggesting you chain albs. Have two separate albs , one for internal and one for external. – erik258 Feb 14 '18 at 15:24
  • The challenge is that we are using ECS and one container can't register to two ALBs. If a single microservice has both types of endpoints (public and private), we may end up to run two ECS with two respective ALB so expose internally and externally, which looks quite redundant from infra and management prospective. If anything would not work, we may choose proxy set up in public VPN and move ALB to private ALB. – Rahul Garg Feb 14 '18 at 17:45
  • One container can't register to 2 ELBs, unfortunately; but there's no reason you can't have each service register to a different ALB. That does mean you can't run the public and private side of a service from the same service definition. But you can run your service twice, with one behind the public and one behind the private. I wouldn't build services that way, but if I had to host one, that's what I'd do. This has been an interesting question for me, thanks for the feedback. I hope you end up with something you like. – erik258 Feb 15 '18 at 16:02
  • Thanks, Dan. I just want to clarify one thing that when you are saying run service twice, you mean run two separate containers under separate ECS service, one will register with public ALB and the second one will register with private ALB, correct? – Rahul Garg Feb 17 '18 at 17:07
  • Yes, exactly. It's perhaps a bit "wasteful", but fits well within the limitations of alb. – erik258 Feb 21 '18 at 00:20
0

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

0

This how we eventually solved.

  1. Two LB one in private and one in public subnet.
  2. Some APIs meant to be public, so directly exposed through public LB.
  3. 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.
Rahul Garg
  • 4,069
  • 1
  • 34
  • 31
0

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.

Miles
  • 1,682
  • 1
  • 13
  • 22
0

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.

claytond
  • 1,061
  • 9
  • 22
-1

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.

MrDuk
  • 16,578
  • 18
  • 74
  • 133
  • Security Groups would work if ELB has different listeners for public and private endpoints. That way you can filter incoming requests by listener's port. It's possible, but not ideal. Instead you can enable WAF for ALB and configure a set of rules. – Victor Feb 12 '18 at 22:36
  • 1
    Segregating internal from external endpoints (ports) is actually pretty standard practice. – MrDuk Feb 12 '18 at 22:40
  • 1
    Just like with the alb itself, a security group attached to an elb will see either internal traffic or external, but not both. You can't have internal and external listeners on the same alb, so this won't work unless you want to make all traffic public and then firewall it. Bear in mind that the external traffic won't be free either, which traffic in the same az on internal addresses would be. – erik258 Feb 12 '18 at 22:55
  • Right, the idea is just that -- if you want to maintain a single LB, allowing all traffic and fire-walling the protected ports is the way to do it. Maintaining a single security group with fire-walled internal ports is a lot easier than maintaining two of everything. Maybe not _preferred_, but easier. – MrDuk Feb 12 '18 at 23:01