Amazon API Gateway in front of ELB and ECS Cluster

31,170

Solution 1

This seems to be a huge missing piece for the API gateway technology, given the way it's pushed. Not being able to call into an internal-facing server in the VPC severely restricts its usefulness as an authentication front-door for internet access. FWIW, in Azure, API Management supports this out of the box - it can accept requests from the internet and call directly into your virtual network which is otherwise firewalled off. The only way this seems to be possible under AWS is using Lambdas, which adds a significant layer of complexity, esp. if you need to support various binary protocols.

Solution 2

Looks like this support has now been added. Haven't tested, YMMV:

https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-api-gateway-supports-endpoint-integrations-with-private-vpcs/

Solution 3

We decided to use a header to check to make sure all traffic is coming through API Gateway. We save a secret in our apps environmental variables and tell the API Gateway to inject that when we create the API. Then check for that key in our app.

Here is what we are doing for this:

In our base controller we check for the key (we just have an REST API behind the gateway):

string ApiGatewayPassthroughHeader = context.HttpContext.Request.Headers["ApiGatewayPassthroughHeader"];

if (ApiGatewayPassthroughHeader != Environment.GetEnvironmentVariable("ApiGatewayPassthroughHeader"))
{
    throw new error;
}

In our swagger file (we are using swagger.json as the source of our APIs)

"x-amazon-apigateway-integration": {
    "type": "http_proxy",
    "uri": "https://${stageVariables.url}/path/to/resource",
    "httpMethod": "post",
    "requestParameters": {
      "integration.request.header.ApiGatewayPassthroughHeader": "${ApiGatewayPassthroughHeader}"
    }
  },

In our docker compose file (we are using docker, but the same could be used in any settings file)

services:
  example:
      environment:
        - ApiGatewayPassthroughHeader=9708cc2d-2d42-example-8526-4586b1bcc74d

At build time we take the secret from our settings file and replace it in the swagger.json file. This way we can rotate the key in our settings file and API gateway will update to use the key the app is looking for.

Solution 4

I know this is an old issue, but I think they may have just recently added support.

"Amazon API Gateway announced the general availability of HTTP APIs, enabling customers to easily build high performance RESTful APIs that offer up to 71% cost savings and 60% latency reduction compared to REST APIs available from API Gateway. As part of this launch, customers will be able to take advantage of several new features including the ability the route requests to private AWS Elastic Load Balancers (ELB), including new support for AWS ALB, and IP-based services registered in AWS CloudMap. "

https://aws.amazon.com/about-aws/whats-new/2020/03/api-gateway-private-integrations-aws-elb-cloudmap-http-apis-release/

Solution 5

Currently there is no way to put API Gateway in front of private ELB, so you're right that it has to be internet facing. The best workaround for your case I can think of would be to put ELB into TCP pass through mode and terminate client certificate on your end hosts behind the ELB.

Share:
31,170
Admin
Author by

Admin

Updated on January 13, 2022

Comments

  • Admin
    Admin 8 months

    I'm trying to put an Amazon API Gateway in front of an Application Load Balancer, which balances traffic to my ECS Cluster, where all my microservices are deployed. The motivation to use the API Gateway is to use a custom authorizer through a lambda function.

    System diagram

    enter image description here

    In Amazon words (https://aws.amazon.com/api-gateway/faqs/): "Proxy requests to backend operations also need to be publicly accessible on the Internet". This forces me to make the ELB public (internet-facing) instead of internal. Then, I need a way to ensure that only the API Gateway is able to access the ELB outside the VPC.

    My first idea was to use a Client Certificate in the API Gatway, but the ELB doesn't seem to support it.

    Any ideas would be highly appreciated!