How to expose APIs endpoints from private AWS ALB - amazon-web-services

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.

Related

AWS Private Link vs VPC Endpoint

What is the difference between Private Link and VPC endpoint? As per the documentation it seems like VPC endpoint is a gateway to access AWS services without exposing the data to internet. But the definition about AWS private link also looks similar.
Reference Link:
https://docs.aws.amazon.com/vpc/latest/userguide/endpoint-services-overview.html
Does Private Link is the superset of VPC endpoint?
It would be really helpful if anyone provides the difference between these two with examples!
Thanks in Advance!
AWS defines them as:
VPC endpoint — The entry point in your VPC that enables you to connect privately to a service.
AWS PrivateLink — A technology that provides private connectivity between VPCs and services.
So PrivateLink is technology allowing you to privately (without Internet) access services in VPCs. These services can be your own, or provided by AWS.
Let's say that you've developed some application and you are hosting it in your VPC. You would like to enable access to this application to services in other VPCs and other AWS users/accounts. But you don't want to setup any VPC peering nor use Internet for that. This is where PrivateLink can be used. Using PrivateLink you can create your own VPC endpoint services which will enable other services to use your application.
In the above scenario, VPC interface endpoint is a resource that users of your application would have to create in their VPCs to connect to your application. This is same as when you create VPC interface endpoint to access AWS provided services privately (no Internet), such as Lambda, KMS or SMS.
There are also Gateway VPC endpoints which is older technology, replaced by PrivateLink. Gateways can only be used to access S3 and DynamoDB, nothing else.
To sum up, PrivateLink is general technology which can be used by you or AWS to allow private access to internal services. VPC interface endpoint is a resource that the users of such VPC services create in their own VPCs to interact with them.
Suppose there is a website xyz.com that I am hosting in a bunch of Ec2 instances, exposed to the outside world thru a Network load balancer.
Now, a client who has his/her own AWS account, wants to access this xyz.com from an Ec2 running in their aws account.
One approach is to go thru the Internet.
However the client wants to avoid the internet route.
He/she wants to use the AWS backbone to reach xyz.com.
The technology that enables that, is AWS Private link.
(note that if you search for Private Link in the AWS services, there will be none.
You will get "End point services" as the closest hit)
So, this is how to route traffic through the AWS backbone:
I, the owner of xyz.com, will create a VPC End Point Service (NOTE the keyword Service here)
The VPC End point service will point to my Network load balancer.
I will then give my VPC End point service name to the client.
The client will create a VPC End Point (NOTE.. this is different from #1).
While creating it, the client will specify the VPC End Point Service name (from #1) that he got from me.
I can choose to be prompted to accept the connection from the client to my VPC End point service.
As soon as I accept it, then the client can reach xyz.com from his/her EC2 instance.
There is no Internet, no direct connect or VPN.. this simply works; and its secure.
And which technology enabled it.. AWS Private link !!!
PRIVATE LINK IS THE ONLY TECHNOLOGY THAT ALLOWS 2 VPCS TO CONNECT THAT HAVE OVERLAPPING CIDR RANGES.
A useful way in understanding differences is in how they technically connect private resources to public services.
Gateway Endpoints route traffic by adding prefix lists within a VPC route table which targets the Gateway endpoint. It is a logical gateway object similar to a Internet Gateway.
In contrast, an Interface Endpoint uses Privatelink to inject into a VPC at the subnet level, via an Elastic Network Interface (ENI), giving network interface functionality, and therefore, DNS and private IP addressing as a means to connect to AWS public services, rather than simply being routed to it.
The differences in connections offer differing advantages and disadvantages (availability, resiliency, access, scalability, and etc), which then dictates how best to connect private resources to public services.
Privatelink is simply a very much abstracted technology to allow a more simplified connection by using DNS. The following AWS re:Invent offers a great overview of Privatelink: https://www.youtube.com/watch?v=abOFqytVqBU
As you correctly mentioned in the question that both VPC endpoint and AWS private link do not expose to internet. On AWS console under VPC, there is a clear option available to create an endpoint. But there is no option/label to create AWS private link. Actually, there is one more option/label called endpoint service. Creating endpoint service is one way to establish AWS private link. At one side of this AWS private link is your endpoint service and at the other side is your endpoint itself. And interestingly we create both these sides in two different VPCs. In other words, you are connecting two VPCs with this private link (instead of using internet or VPC peering).
understand like,
VPC1 got endpoint service ----> private link -----> VPC2 got endpoint
Here endpoint service side is service provider while endpoint is service consumer. So when you have some service (may be some application or s/w) that you think other VPC endpoints can consume you create endpoint service at your end and consumers will create endpoints at there end. When consumers create endpoints at their end they have to give/select your service name and thus private link will be established with your service.
Ultimately you can have multiple consumers of your service just like one to many relationship.

ECS Fargate cross microservice communication options

I have been looking into different ways of connecting multiple miscorservices within their own services/tasks using ECS Fargate.
Normally, if all microservices are defined in the same task definition, we can just use the local ip with corresponding ports but this means we cannot scale individual microservices. From what I can tell there are two 'main' ways of enabling this communication when we break these out into multiple services:
Add a load balancer to each service and use the loadbalancers public ip as the single point of access from one service to another.
Questions I have on this is:
a. Do all the services that need to communicate need to sit in the same VPC and have the
service's incoming rules set to the security group of the load balancer?
b. Say we have now provisioned the entire set up and need to set one of the loadbalancer public DNS's in one microservices code base, whats the best way of attaining this, im guessing some sort of terraform script that 'assumes' the public DNS that will be added to it?
Making use of AWS Service Discovery, meaning we can query service to service with a simple built up identifier.
Question I have for this is:
a. Can we still attach load balancers to the services and STILL use service discovery? Or
does service discovery have an under the hood load balancer already configured?
Many thanks in advance for any help!
1.a All services in the same VPC and their security groups (SGs)
I assume that you are talking about case where each service will have its own load balancer (LB). Since the LBs are public, they can be in any VPC, region or account.
SGs are generally setup so that incoming rules to services allow only connections from the SG of the LB.
1.b DNS
Each task can have environmental variables. This is a good way to pass the DNS values. If you are taking about terraform (TF), then TF would provision the LBs and then create the tasks and set the env variables with DNS values of the LBs. Thus, you would know the DNS of LBs as they would have been created before your services.
2.a Service discovery (SD)
SD is only for private communication between services. No internet is involved, so everything must be in same VPC or peered-VPCs. So its basically oposite of the first solution with LBs.
I think you should be able to also use public LB along with SD.
SD does not use a LB. Instead when you query a DNS of a service through SD you will get private IP addresses of the tasks in random order. So the random order approximates load balancing of connections between tasks in a service.

Do I need a loadbalancer in an AWS elastic beanstak environment

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.

AWS ECS Private and Public Services

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

AWS keeping services on domain instead of having public

I have hosted few services on AWS however all are public and can be accessed from anywhere which is a security threat, could you please let me know how to keep the services specific to internal users of organization without any authentication medium.
I found a workaround for this, if you have list of IP range may be a network administrator can help you, take that and put them in load balancers under security group.
You should spend some time reviewing security recommendations on AWS. Some excellent sources are:
Whitepaper: AWS Security Best Practices
AWS re:Invent 2017: Best Practices for Managing Security Operations on AWS (SID206) - YouTube
AWS re:Invent 2017: Security Anti-Patterns: Mistakes to Avoid (FSV301) - YouTube
AWS operates under a [Shared Responsibility Model, which means that AWS provides many security tools and capabilities, but it is your responsibility to use them correctly!
Basic things you should understand are:
Put public-facing resources in a Public Subnet. Everything else should go into a Private Subnet.
Configure Security Groups to only open a minimum number of ports and IP ranges to the Internet.
If you only want to open resources to "internal users of organization without any authentication medium", then you should connect your organization's network to AWS via AWS Direct Connect (private fiber connection) or via an encrypted VPN connection.
Security should be your first consideration in everything you put in the cloud — and, to be honest, everything you put in your own data center, too.
Consider a LEAST PRIVILEGE approach when planning Network VPC Architecture, NACL and Firewall rules as well as IAM Access & S3 Buckets.
LEAST PRIVILEGE: Configure the minimum permission and Access required in IAM,Bucket Policies, VPC Subnets, Network ACL and Security Groups with a need to know White-list approach.
Start from having specific VPCs with 2 Main Segments of Networks 1-Public and the other 2-Private.
You will place your DMZ components on the Public segment,
Components such as Internet Facing Web Server, load Balancers,
Gateways, etc falls here.
For the Rest such as Applications, Data, or Internal Facing
LoadBalancers or WebServers make sure you place them in the Private
Subnet where you will use an Internal IP address from specified
Internal Range to refer to the Components Inside the VPC.
If you have Multiple VPCs and you want them to talk with each
other you can Peer them together.
You also can use Route53 Internal DNS to simplify naming.
Just in case, If you need to have Internet access from the Private segment
you can Configure a NAT Gateway on the public subnet and handle
Outgoing Traffic routed to Internet from the NAT Gateway.
S3 Buckets can be Configured and Servered as VPC-END points. (Routing via an Internal Network rather than Internet Routed to S3 Buckets/Object).
In IAM you can create Policies to whitelist source IP and attached to Roles and Users which is a great combination to Mix Network VPN Connections/white-listed IPs and keep Network Access in harmony with IAM. That means even Console Access could be governed by a White-listed Policy.