Is there a way to connect ALB to an API Gateway privately?

137 Views Asked by At

I have the following Fargate service using the ALB:

    const sbApp = new ApplicationLoadBalancedFargateService(
    this,
    "GithubReposApp",
    {
        cluster: appCluster,
        desiredCount: 1,
        cpu: 256,
        memoryLimitMiB: 512,
        taskImageOptions: {
            image: ecs.ContainerImage.fromAsset(".."),
            containerPort: 8080,
            secrets: {
                GITHUB_TOKEN: ecs.Secret.fromSecretsManager(
                    appSecrets,
                    "githubToken"
                ),
            },
        },
        assignPublicIp: true,
        publicLoadBalancer: true,
    }
);

I managed to connect a Rest API to the ALB, but with the public DNS.

const api = new RestApi(this, "GithubReposApi", {
    restApiName: "GithubReposApi",
});

const apiGithub = api.root.addResource("api");
const proxyResource = new ProxyResource(this, "GithubReposProxy", {
    parent: apiGithub,
    anyMethod: false,
});

proxyResource.addMethod(
    "GET",
    new HttpIntegration(
        `http://${sbApp.loadBalancer.loadBalancerDnsName}/api/{proxy}`,
        {
            proxy: true,
            httpMethod: "GET",
            options: {
                requestParameters: {
                    "integration.request.path.proxy": "method.request.path.proxy",
                },
            },
        }
    ),
    {
        requestParameters: {
            "method.request.path.proxy": true,
        },
    }
);

Is there a way to connect privately the API Gateway with the ALB? I know it must have, but I already tried a lot of things and nothings seems to work.

Thanks for your help.

1

There are 1 best solutions below

0
Jonas Geiler On

What you might want to try is setting publicLoadBalancer and assignPublicIp to false, in order to get a private ALB and ECS Service. Then, if possible, you should use a newer HTTP API Gateway instead of the older REST API Gateways. The HttpApi can be found in the aws-cdk-lib/aws-apigatewayv2 library. The reason you'd want to switch to a HTTP API is to be able to use the HttpAlbIntegration from the aws-cdk-lib/aws-apigatewayv2-integrations library, which provides an easy method of connecting an API Gateway to an ALB using an VPC-Link, like so:

import { HttpApi, HttpMethod } from 'aws-cdk-lib/aws-apigatewayv2';
import { HttpAlbIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations';

// Create a HTTP API
const api = new HttpApi(this, 'GithubReposApi');

api.addRoutes({
    path: '/{proxy+}',
    methods: [ HttpMethod.ANY ],

    // Use the `HttpAlbIntegration` here:
    integration: new HttpAlbIntegration(
        'GithubReposAppIntegration',

        // The `ApplicationLoadBalancedFargateService` construct provides a
        // `listener` attribute which can be passed in here:
        sbApp.listener, 
    ),
});

If you are not able to switch from a REST API Gateway to a HTTP API Gateway, you could give the AwsIntegration construct from the aws-cdk-lib/aws-apigateway library a try, but unfortunately I have never tried it.

One thing you should watch out for, which was a mistake that took me 2 days to find, is setting restrictDefaultSecurityGroup to false on the VPC that the ECS cluster uses:

const vpc = new Vpc(
    this,
    'ClusterVpc',
    {
        maxAzs: 2,

        // Add this:
        restrictDefaultSecurityGroup: false,
    },
);

This disables the removal of certain security group rules which are needed for the API Gateway to be able to access the VPC over the VPC-Link.