Amazon API Gateway to AWS Fargate via VPC Link and Network Load Balancer

This pattern connects a public API Gateway to a private Network Load Balancer to ECS Fargate cluster. It keeps the private subnet resources safe.

Amazon API GatewayVPC LinkNLBAWS Fargate
import aws_cdk as cdk
from aws_cdk import (
    Stack,
    aws_apigateway as apigw,
    aws_ec2 as ec2,
    aws_ecs as ecs,
    aws_ecs_patterns as ecs_patterns
)


from constructs import Construct

class ApigwVpclinkPvtnlbFargateCdkPyStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Create a VPC
        vpc = ec2.Vpc(self, "Vpc",
         max_azs=2,
         cidr="10.1.0.0/16",
         subnet_configuration=[
             ec2.SubnetConfiguration(name="private-snet",
                                     subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS,
                                     cidr_mask=24),
            ec2.SubnetConfiguration(name="public-snet",
                                     subnet_type=ec2.SubnetType.PUBLIC,
                                     cidr_mask=24)]

        )

        # Create a Fargate cluster
        cluster = ecs.Cluster(self, "Cluster",
            vpc=vpc
        )

        # Create a task definition
        task_def = ecs.FargateTaskDefinition(
            self, 'TaskDef',
            cpu=512, 
            memory_limit_mib=1024,
        )

        # create container with amazon ecs sample image
        container = task_def.add_container(
            'Container',
            image=ecs.ContainerImage.from_registry('amazon/amazon-ecs-sample'),
            memory_limit_mib=512,
        )

        # Add port mappings
        container.add_port_mappings(
            ecs.PortMapping(
                container_port=80,
                host_port=80
            )
        )
        
        # security group for the service
        service_sg = ec2.SecurityGroup(self, "Service_SG", vpc=vpc)

        service_sg.add_ingress_rule(
            peer=ec2.Peer.ipv4(vpc.vpc_cidr_block),
            connection=ec2.Port.tcp(80),
            description="Allow HTTP from NLB"
        )

        # Create a service
        service = ecs_patterns.NetworkLoadBalancedFargateService(self, "Service",
            cluster=cluster,
            task_definition=task_def,
            public_load_balancer=False,
            security_groups=[service_sg]
        )

        # Create an NLB
        nlb = service.load_balancer

        # nlb.load_balancer_security_groups[0] = ec2.SecurityGroup(self, 'LoadBalancerSG', vpc=vpc, allow_all_outbound=False)
        


        # Create an API
        apigateway = apigw.RestApi(self, "serverless-pattern-api")

        # Create a VPC link targeting the NLB
        link = apigw.VpcLink(self, "Link", targets=[nlb])

        # API gw proxy resource
        root = apigateway.root.add_resource("{proxy+}")

        vpc_integration = apigw.Integration(
            type=apigw.IntegrationType.HTTP,
            integration_http_method= "ANY",
            uri="http://" + nlb.load_balancer_dns_name + "/{proxy}",
            options=apigw.IntegrationOptions(
                connection_type=apigw.ConnectionType.VPC_LINK,
                vpc_link=link,
                request_parameters =  { 'integration.request.path.proxy': 'method.request.path.proxy' },
                integration_responses=[
                    apigw.IntegrationResponse(
                        status_code="200",
                        response_templates={
                            "application/json": ""
                        },
                    )
                ]
            ),
        )

        # Integrate the method with the VPC link
        root.add_method("ANY", vpc_integration,
                        request_parameters= { 'method.request.path.proxy': True },
                        method_responses=[
                                apigw.MethodResponse(
                                    # Successful response from the integration
                                    status_code="200"
                                    # Validate the schema on the response
                                )
                            ])

Download

git clone https://github.com/aws-samples/serverless-patterns
cd serverless-patterns/apigw-vpclink-pvtnlb-fargate-cdk-python

Pattern repository

View on GitHub

Last updated on 26 Dec 2024

Edit this page