AWS HTTP API Gateway URL Based Routing - amazon-web-services

Okay so here is my requirement. I want to have end points for my customers like so:
https://customer-a.mydomain.com
https://customer-b.mydomain.com
Now, when we access the customer-a endpoint above, I expect AWS to route the request to customer A's ECS Fargate service which is load balanced by https://customer-a-elb.mydomain.com
Similarly, when we access the customer-b endpoint above, I expect AWS to route the request to customer B's ECS Fargate service which is load balanced by https://customer-b-elb.mydomain.com
The plan was, from my DNS, I would route everyone who accesses *.mydomain.com (wild card DNS entry) to the same API Gateway in AWS. And let the API Gateway determine which load balancer to route to depending on the base URL.
I was hoping this can be easily achieved using AWS API Gateway but so far I have not been able to find a solution to implement this. From what I understand, it is only possible to do path based routing (as opposed to base URL based routing which is really what I need in this case).
Any hints would be much appreciated.
CLARIFICATION :
per my requirement, both the customers need to access the same path /myservice but on different ELBs. For e.g.
https://customer-a.mydomain.com/service1 -> https://customer-a-elb.mydomain.com/service1
https://customer-b.mydomain.com/service1 -> https://customer-b-elb.mydomain.com/service1
Somehow I think path based routing cant handle this scenario - as we can define only one route for a path.

API Gateway supports path-based routing. And you can configure which resources will receive incoming API requests based on the URL requested by the client. The following example may help you.link

Related

Can I get an example of how to connect a lambda function to a domain name?

I've been wasting about 12 hours going in circles in what seems like this:
I am trying to just make a simple static landing page in lambda and hook the root of a domain to it.
The landing page works, but api gateway didn't because AWS doesn't seem to set permissions properly by default ("internal server error" with API gateway and lambda on AWS) but now the gateway link works.
So the next steps were the following:
add a custom domain name in the api gateway
add the api mapping in the custom domain name
in route 53, create a wildcard certificate with *.domain.com and domain.com
create an A record that points to the api gateway with domain.com
create a CNAME record that points to the A record
and I get an error 403 with absolutely nothing in the log. I log both 'default' and '$default' stages in the api gateway.
I read https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-403-error-lambda-authorizer/ which is all about looking at what's in the logs...
and I find the doc is both everywhere and nowhere because it's built as chunks of 'do this' and 'do that' without ever painting a whole picture of how each piece is connected to the other, or any graph with the hierarchy of services, etc. Reminds me of code that works only when you follow the example documented and breaks otherwise.
I'm sure I'm doing something wrong, but given the lack of logs and lack of cohesive documentation, I have no idea about the problem.
Not to mention that http doesn't even connect, just https.
Can anyone outline the steps needed to achieve this? essentially: [http|https]://(www).domain.com -> one lambda function
You cannot use API Gateway for an HTTP request; it only supports HTTPS.
From the Amazon API Gateway FAQs (emphasis mine):
Q: Can I create HTTPS endpoints?
Yes, all of the APIs created with Amazon API Gateway expose HTTPS endpoints only. Amazon API Gateway does not support unencrypted (HTTP) endpoints. By default, Amazon API Gateway assigns an internal domain to the API that automatically uses the Amazon API Gateway certificate. When configuring your APIs to run under a custom domain name, you can provide your own certificate for the domain.
You can use CloudFront to automatically redirect HTTP to HTTPS. How do I set up API Gateway with my own CloudFront distribution? provides a pretty simple walkthrough of connecting an API Gateway to CloudFront (you can skip the API Gateway portion and use the one you created). The important thing you'll need to do that is not in that document is to select Redirect HTTP to HTTPS.
If you truly need HTTP traffic you're probably going to need to go with an ALB.

AWS Route 53 with AWS API Gateway

Currently I have many AWS Lambda deployed already. And then I think of how to perform Performance Test for each of AWS Lambda. The solution I decided to go is
- Expose each API using AWS Api Gateway for each AWS Lambda
- Use JMeter (Neoload) to perform "performance test" for an API.
The approach is working fine except we need to use a generated endpoint from AWS like https://tl8drdruob.execute-api.us-west-1.amazonaws.com/dev. Now I would like to see if we can use Route 53 to route API or not.
We do have an host zone like abc.awsnonprod.mycompany.net. And I trying to add a record set to that host zone but I don't see any my API Gateway end points listing on Alias Target (API Gateway).
Please advice me if I missing something here.
Thank you
It seems you need to have the custom domain name to map the route 53 to API Gateway.
Please follow Set Up a Custom Domain Name for an API in API Gateway
The API Gateway custom domain feature is very likely what you want. It will create a special/internal Cloudfront distribution which you can use to manipulate the domain and path. You can even relate it to API Gateway stages. Then you could use Route 53 to CNAME or A (alias) your custom domain to the CloudFront distribution.

how to add AWS API gateway with application load balancer for ECS?

How to integrate API gateway with application load balancer? I have integrated ECS with ALB, now I want to add API gateway in front without lambda. But I got confused how to connect API gateway with ALB..
What you're probably looking for is the HTTP Proxy Integration as described here
The basic idea is this:
Set up your API-Gateway with a greedy path like /{proxy+} on the ANY Method
Set the backend-endpoint to https://my-alb-endpoint.com/ecs-service-bla/{proxy}
(hopefully) success
To make this work, your backend needs to be exposed to the internet (or at least reachable for the API Gateway)!
You probably should keep your backend within a locked down VPC, but for this you're going to need to set up a private integration, which requires a Network Load balancer - this might be costlier, but would be the recommended approach.
Yes you can do . Inside API Gateway under integration type select HTTP and then provide complete path of ALB with endpoint resource.

Regional/Edge-optimized API Gateway VS Regional/Edge-optimized custom domain name

This does not make sense to me at all. When you create a new API Gateway you can specify whether it should be regional or edge-optimized. But then again, when you are creating a custom domain name for API Gateway, you can choose between the two.
Worst of all, you can mix and match them!!! You can have a regional custom domain name for an edge-optimized API gateway and it's absolutely meaningless to me!
Why these two can be regional/edge-optimized separately? And when do I want each of them to be regional/edge-optimized?
Why these two can be regional/edge-optimized separately?
Regional and Edge-Optimized are deployment options. Neither option changes anything fundamental about how the API is processed by the AWS infrastructure once the request arrives at the core of the API Gateway service or how the services behind API Gateway ultimately are accessed -- what changes is how the requests initially arrive at AWS and are delivered to the API Gateway core for execution. More about this, below.
When you use a custom domain name, your selected API stage is deployed a second time, on a second endpoint, which is why you have a second selection of a deployment type that must be made.
Each endpoint has the characteristics of its deployment type, whether regional or edge-optimized. The original deployment type of the API itself does not impact the behavior of the API if deployed with a custom domain name, and subsequently accessed using that custom domain name -- they're independent.
Typically, if you deploy your API with a custom domain name, you wouldn't continue to use the deployment endpoint created for the main API (e.g. xxxx.execute-api.{region}.amazonaws.com), so the initial selection should not matter.
And when do I want each of them to be regional/edge-optimized?
If you're using a custom domain name, then, as noted above, your original deployment selection for the API as a whole has no further impact when you use the custom domain.
Edge-optimized endpoints were originally the only option available. If you don't have anything on which to base your selection, this choice is usually a reasonable one.
This option routes incoming requests through the AWS "Edge Network," which is the CloudFront network, with its 100+ global edge locations. This does not change where the API Gateway core ultimately handles your requests -- they are still ultimately handled within the same region -- but the requests are routed from all over the world into the nearest AWS edge, and they travel from there on networks operated by AWS to arrive at the region where you deployed your API.
If the clients of your API Gateway stage are globally dispersed, and you are only deploying your API in a single region, you probably want an edge-optimized deployment.
The edge-optimized configuration tends to give you better global responsiveness, since it tends to reduce the impact of network round trips, and the quality of the transport is not subject to as many of the vagaries of the public Internet because the request covers the least amount of distance possible before jumping off the Internet and onto the AWS network. The TCP handshake and TLS are negotiated with the connecting browser/client across a short distance (from the client to the edge) and the edge network maintains keep-alive connections that can be reused, all of which usually works in your favor... but this optimization becomes a relative impairment when your clients are always (or usually) calling the API from within the AWS infrastructure, within the same region, since the requests need to hop over to the edge network and then back into the core regional network.
If the clients of your API Gateway stage are inside AWS and within the same region where you deployed the API (such as when the API is being called by other systems in EC2 within the region), then you will most likely want a regional endpoint. Regional endpoints route requests through less of the AWS infrastructure, ensuring minimal latency and reduced jitter when requests are coming from EC2 within the same region.
As a side-effect of routing through the edge network, edge-optimized endpoints also provide some additional request headers that you may find useful, such as CloudFront-Viewer-Country: XX which attempts to identify the two-digit country code of the geographic location of the client making the API request. Regional endpoints don't have these headers.
As a general rule, go with edge-optimized unless you find a reason not to.
What would be some reasons not to? As mentioned above, if you or others are calling the API from within the same AWS region, you probably want a regional endpoint. Edge-optimized endpoints can introduce some edge-case side-effects in more advanced or complicated configurations, because of the way they integrate into the rest of the infrastructure. There are some things you can't do with an edge-optimized deployment, or that are not optimal if you do:
if you are using CloudFront for other sites, unrelated to API Gateway, and CloudFront is configured for a wildcard alternate domain name, like *.example.com, then you can't use a subdomain from that wildcard domain, such as api.example.com, on an edge-optimized endpoint with a custom domain name, because API Gateway submits a request to the edge network on your behalf to claim all requests for that subdomain when they arrive via CloudFront, and CloudFront rejects this request since it represents an unsupported configuration when used with API Gateway, even though CloudFront supports it in some other circumstances.
if you want to provide redundant APIs that respond to the same custom domain name in multiple regions, and use Route 53 Latency-Based Routing to deliver requests to the region nearest to the requester, you can't do this with an edge-optimized custom domain, because the second API Gateway region will not be able to claim the traffic for that subdomain on the edge network, since the edge network requires exactly 1 target for any given domain name (subdomain). This configuration can be achieved using regional endpoints and Route 53 LBR, or can be achieved while leveraging the edge network by using your own CloudFront distribution, Lambda#Edge to select the target endpoint based on the caller's location, and API Gateway regional deployments. Note that this can't be achieved by any means if you need to support IAM authentication of the caller, because the caller needs to know the target region before signing and submitting the request.
if you want to use your API as part of a larger site that integrates multiple resources, is deployed behind CloudFront, and uses the path to route to different services -- for example, /images/* might route to an S3 bucket, /api/* might route to your API Gateway stage, and * (everything else) might route to an elastic load balancer in EC2 -- then you don't want to use an edge-optimized API, because this causes your requests to loop through the edge network twice (increasing latency) and causes some header values to be lost. This configuration doesn't break, but it isn't optimal. For this, a regional endpoint is desirable.

Serving the static content (EC2) and REST services (API Gateway) from the same address

I have a website which I serve using express running in an EC2 instance. But this EC2 serves only the static content (html, js, css) and the dynamic part comes from API Gateway. Right now, these two have different IPs (and domains) which means that I have to deal with CORS problems accessing API Gateway from the web pages. If I could somehow serve the static content and dynamic one through the same address, that would be much better.
The way I see it, this can be done in two ways. I can serve both of them on the same host but different ports which I'm not sure if it's going to solve the same CORS problem or not. But another way which I'm sure it will not face the CORS problem is serving API Gateway under some specific sub-folder. Like http://example.com/api while the static content is served from any url except that.
Does anyone know how can I do this? Is CloudFront what I need? Or Elastic Load Balancer?
Yes, CloudFront is what you need for this scenario.
Application Load Balancer can also do path-based routing, but it doesn't support API Gateway as a target.
By default, CloudFront can route requests under a single domain to the correct choice from up to 25 destinations, using up to 25 path (matching) patterns (both of these limits can be increased by request, but it sounds like for now, you only need 2 of each, /api/* to the API, and the default * route to EC2). You can also leverage this setup to put some static content in an S3 bucket and take some load off of the servers in EC2.
For this configuration, you will want to configure your API Gateway deployment with a regional endpoint, not an edge optimized endpoint. This is because edge optimized endpoints already use part of the CloudFront infrastructure (a part to which you have no ability to configure), so using an edge-optimized endpoint behind your own CloudFront distribution sends each request and response through the CloudFront network twice, increasing latency.