amazon-web-servicesaws-lambdaaws-api-gatewayamazon-ecsaws-cdk

How to integrate AWS Lambda to Application Load Balanced Fargate Service


I'm trying to protect an endpoint (e.g., /protected) in my API hosted on an application load balanced Fargate service (ALB) using a JWTAuthorizer Lambda function.

But I couldn't really find a good example that showing how can I do it. So far I tried:

private createContainerCopilotService() {

    const cluster = new ecs.Cluster(this.stack, 'Cluster', {
        vpc: this.stack.resources.external.vpc,
        clusterName: `${this.config.getStackName()}-Cluster`,
        containerInsights: true,
    });


    const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this.stack, 'LoadBalancedService', {
        cluster,
        memoryLimitMiB: 1024,
        desiredCount: 1,
        cpu: 512,
        publicLoadBalancer: true,
        redirectHTTP: true,
        protocol: aws_elasticloadbalancingv2.ApplicationProtocol.HTTPS,
        taskImageOptions: {
            image: ecs.ContainerImage.fromAsset('.',
                {
                    file: 'src/docker/Dockerfile',
                    buildArgs: { NODE_VERSION: '20' },
                },
            ),
            environment: {
                // Env variables
            },
        },
        loadBalancerName: `${this.config.getStackName()}-LoadBalancer`,
        domainName: this.config.getDomainName(),
        domainZone: this.stack.resources.external.hostedZone,
        securityGroups: [this.stack.resources.external.consumerOpenSearchAccessSecurityGroup],
    });

    loadBalancedFargateService.targetGroup.configureHealthCheck({
        path: '/',
    });

    return loadBalancedFargateService;
}

private createApiGateway(loadBalancedFargateService: ecsPatterns.ApplicationLoadBalancedFargateService) {

    const api = new apigw2.HttpApi(this.stack, 'HttpGateWay');

    const jwtAuthorizerFunction = lambda.Function.fromFunctionAttributes(
        this.stack,
        'ImportedJwtAuthorizer',
        {
            functionArn: this.config.getAuthorizerLambdaArn(),
            skipPermissions: true,
        }
    );

    const jwtAuthorizerIntegration = new apigw.LambdaIntegration(jwtAuthorizerFunction);

    api.addRoutes({
        path: '/sessions/{proxy+}',
        methods: [apigw2.HttpMethod.GET],
        integration: new apigw2Integrations.HttpAlbIntegration('AuthIntegration', loadBalancedFargateService.listener,
            {
                // Here I don't know how can I use the jwtAuthorizerIntegration
            }
        )
    })
}

Does anyone have experience with connecting Lambda functions to ALBs. Shall I use API Gateway or any suggestions on how to properly secure the endpoint using the Lambda authorizer?


Solution

  • check the lib aws-cdk-lib/aws-apigatewayv2-authorizers: and import this class HttpLambdaAuthorizer

    after creating the authorizer you can attach it in a way similar to this:

        const apiGateway = new HttpApi(this, "ApiGateway", {
            corsPreflight: {
                allowHeaders: ["*"],
                allowCredentials: true,
                allowMethods: [
                    CorsHttpMethod.PATCH,
                    CorsHttpMethod.POST,
                    CorsHttpMethod.GET,
                    CorsHttpMethod.PUT,
                    CorsHttpMethod.DELETE,
                    CorsHttpMethod.OPTIONS,
                ],
                allowOrigins: ["*"
                ],
                maxAge: cdk.Duration.days(1),
            },
            defaultAuthorizer: lambdaAuthorizer,
        });