diff --git a/apigw-rest-vpclink-pvt-alb-sam/.gitignore b/apigw-rest-vpclink-pvt-alb-sam/.gitignore new file mode 100644 index 000000000..bf44992fd --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-sam/.gitignore @@ -0,0 +1,39 @@ +# SAM +.aws-sam/ +samconfig.toml + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# IDEs +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db diff --git a/apigw-rest-vpclink-pvt-alb-sam/README.md b/apigw-rest-vpclink-pvt-alb-sam/README.md new file mode 100644 index 000000000..2062ba99a --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-sam/README.md @@ -0,0 +1,91 @@ +# Amazon API Gateway REST API to Private HTTP Endpoint via Amazon VPC Link V2 + +This pattern demonstrates direct integration between API Gateway REST API and a private Application Load Balancer using VPC link V2. Previously, connecting REST API Gateway to a private ALB required VPC link V1 with an intermediary Network Load Balancer, adding complexity and cost. VPC Link V2 eliminates this requirement, enabling direct ALB integration for simplified architecture and reduced operational overhead. + +This AWS SAM template deploys a REST API Gateway with Amazon VPC link V2 integration to a private Amazon Application Load Balancer and Amazon ECS Fargate cluster. The API definition is provided via an external OpenAPI specification file (api.yaml). + +### Prerequisites: +* An existing VPC with private subnets +* Private subnets must have internet access (via NAT Gateway) to pull container images from Docker Hub + +### Deployed resources: +* Security Groups for ALB and ECS tasks +* ECS Fargate cluster with service and task definitions +* Private Application Load Balancer with listener and target group +* Amazon VPC link V2 connecting API Gateway to the private ALB +* API Gateway REST API (AWS::Serverless::Api) with proxy integration to the ALB + +Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigw-rest-vpclink-pvt-alb-sam/ + +Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. + +## Requirements + +* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. +* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured +* [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) installed and configured +* [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) installed + +## Deployment Instructions + +1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository: + ``` + git clone https://github.com/aws-samples/serverless-patterns + ``` +2. Change directory to the pattern directory: + ``` + cd serverless-patterns/apigw-rest-vpclink-pvt-alb-sam + ``` +3. From the command line, use AWS SAM to deploy the AWS resources for the pattern. You will be prompted for the VPC ID and private subnet IDs: + ``` + sam deploy --guided --capabilities CAPABILITY_NAMED_IAM + ``` +4. During the prompts: + * Enter a stack name + * Enter the desired AWS Region + * Enter your VPC ID for the VpcId parameter + * Enter your first private subnet ID for the PrivateSubnet1 parameter + * Enter your second private subnet ID for the PrivateSubnet2 parameter + * Allow SAM CLI to create IAM roles with the required permissions + * Accept the defaults for the remaining prompts + + Once you have run `sam deploy --guided` mode once and saved arguments to a configuration file (samconfig.toml), you can use `sam deploy` in future to use these defaults. + +5. Note the outputs from the SAM deployment process. These contain the resource names and/or ARNs which are used for testing. + +## How it works + +This pattern demonstrates secure integration between a public REST API Gateway endpoint and a private Application Load Balancer with an ECS Fargate cluster. The pattern uses AWS::Serverless::Api resource with an external OpenAPI definition (api.yaml) that leverages AWS::Include transform to support CloudFormation intrinsic functions. + +Traffic flows through Amazon VPC Link V2, which provides a secure, private connection from API Gateway to the internal ALB without exposing backend resources to the public internet. The ALB distributes traffic to ECS Fargate tasks running in private subnets. + +## Testing + +The stack outputs the REST API endpoint. Test it by accessing any path through the API: + +```bash +curl https:///index.html +``` + +You should see the nginx welcome page HTML. To check just the status code: + +```bash +curl -s -o /dev/null -w "%{http_code}" https:///index.html ; echo +``` + +Expected response: **200** + +## Cleanup + +1. Delete the stack: + ```bash + sam delete + ``` +2. Confirm the stack has been deleted: + ```bash + aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus" + ``` +---- +Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 diff --git a/apigw-rest-vpclink-pvt-alb-sam/api.yaml b/apigw-rest-vpclink-pvt-alb-sam/api.yaml new file mode 100644 index 000000000..bbb86853d --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-sam/api.yaml @@ -0,0 +1,26 @@ +openapi: 3.0.1 +info: + title: REST API VPC Link Demo + version: '1.0' +paths: + /{proxy+}: + x-amazon-apigateway-any-method: + parameters: + - name: proxy + in: path + required: true + schema: + type: string + x-amazon-apigateway-integration: + type: http_proxy + httpMethod: ANY + uri: + Fn::Sub: 'http://${PrivateALB.DNSName}/{proxy}' + connectionType: VPC_LINK + connectionId: + Ref: VpcLink + integrationTarget: + Ref: PrivateALB + requestParameters: + integration.request.path.proxy: method.request.path.proxy + passthroughBehavior: when_no_match diff --git a/apigw-rest-vpclink-pvt-alb-sam/apigw-rest-vcplink-pvt-alb-sam.json b/apigw-rest-vpclink-pvt-alb-sam/apigw-rest-vcplink-pvt-alb-sam.json new file mode 100644 index 000000000..929207d71 --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-sam/apigw-rest-vcplink-pvt-alb-sam.json @@ -0,0 +1,100 @@ +{ + "title": "Amazon API Gateway REST API with Private ALB integration via VPC link V2", + "description": "This pattern demonstrates integrating an API Gateway REST API with a private Amazon Application Load Balancer using VPC link V2", + "level": "200", + "language": "", + "framework": "AWS SAM", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern deploys an API Gateway REST API endpoint that integrates with a private Application Load Balancer using VPC link V2", + "The private ALB routes traffic to an ECS Fargate cluster running containerized applications", + "The pattern creates all required security groups, IAM roles, and networking components for secure private integration" + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apigw-rest-vpclink-pvt-alb-sam", + "templateURL": "serverless-patterns/apigw-rest-vpclink-pvt-alb-sam", + "projectFolder": "apigw-rest-vpclink-pvt-alb-sam", + "templateFile": "template.yaml" + } + }, + "resources": { + "bullets": [ + { + "text": "REST API private integration using VPC link", + "link": "https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-private-integration.html" + }, + { + "text": "Working with VPC links for REST APIs", + "link": "https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-vpc-link.html" + }, + { + "text": "Tutorial: Build a REST API with API Gateway private integration", + "link": "https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-with-private-integration.html" + } + ] + }, + "deploy": { + "text": [ + "sam deploy --guided" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "sam delete" + ] + }, + "authors": [ + { + "name": "Abhishek Agawane", + "image": "https://drive.google.com/file/d/1E-5koDaKEaMUtOctX32I9TLwfh3kgpAq/view?usp=drivesdk", + "bio": "Abhishek Agawane is a Security Consultant at Amazon Web Services with more than 8 years of industry experience. He helps organizations architect resilient, secure, and efficient cloud environments, guiding them through complex challenges and large-scale infrastructure transformations. He has helped numerous organizations enhance their cloud operations through targeted optimizations, robust architectures, and best-practice implementations.", + "linkedin": "agawabhi" + } + ], + "patternArch": { + "icon1": { + "x": 15, + "y": 50, + "service": "apigw", + "label": "API Gateway REST API" + }, + "icon2": { + "x": 40, + "y": 50, + "service": "vpc-endpoint", + "label": "VPC link V2" + }, + "icon3": { + "x": 65, + "y": 50, + "service": "alb", + "label": "Application Load Balancer" + }, + "icon4": { + "x": 90, + "y": 50, + "service": "ecs", + "label": "Amazon ECS" + }, + "line1": { + "from": "icon1", + "to": "icon2" + }, + "line2": { + "from": "icon2", + "to": "icon3" + }, + "line3": { + "from": "icon3", + "to": "icon4" + } + } +} diff --git a/apigw-rest-vpclink-pvt-alb-sam/example-pattern.json b/apigw-rest-vpclink-pvt-alb-sam/example-pattern.json new file mode 100644 index 000000000..567f9b39e --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-sam/example-pattern.json @@ -0,0 +1,62 @@ +{ + "title": "REST API Gateway to Private ALB and ECS Fargate via VPC Link V2", + "description": "This pattern demonstrates REST API Gateway integration with a private Application Load Balancer and ECS Fargate cluster using VPC Link V2", + "language": "YAML", + "level": "200", + "framework": "SAM", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern deploys a REST API Gateway endpoint that integrates with a private Application Load Balancer using VPC Link V2", + "The private ALB routes traffic to an ECS Fargate cluster running containerized applications", + "The pattern creates all required security groups, IAM roles, and networking components for secure private integration" + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apigw-rest-vpclink-pvt-alb-sam", + "templateURL": "serverless-patterns/apigw-rest-vpclink-pvt-alb-sam", + "projectFolder": "apigw-rest-vpclink-pvt-alb-sam", + "templateFile": "apigw-rest-vpclink-pvt-alb-sam/template.yaml" + } + }, + "resources": { + "bullets": [ + { + "text": "REST API private integration using VPC link", + "link": "https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-private-integration.html" + }, + { + "text": "Working with VPC links for REST APIs", + "link": "https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-vpc-link.html" + }, + { + "text": "Tutorial: Build a REST API with API Gateway private integration", + "link": "https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-with-private-integration.html" + } + ] + }, + "deploy": { + "text": [ + "sam deploy --guided" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "sam delete" + ] + }, + "authors": [ + { + "name": "Abhishek Agawane", + "image": "https://drive.google.com/file/d/1E-5koDaKEaMUtOctX32I9TLwfh3kgpAq/view?usp=drivesdk", + "bio": "Abhishek Agawane is a Security Consultant at Amazon Web Services with more than 8 years of industry experience. He helps organizations architect resilient, secure, and efficient cloud environments, guiding them through complex challenges and large-scale infrastructure transformations. He has helped numerous organizations enhance their cloud operations through targeted optimizations, robust architectures, and best-practice implementations.", + "linkedin": "https://www.linkedin.com/in/agawabhi/" + } + ] +} diff --git a/apigw-rest-vpclink-pvt-alb-sam/template.yaml b/apigw-rest-vpclink-pvt-alb-sam/template.yaml new file mode 100644 index 000000000..e9f4608c7 --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-sam/template.yaml @@ -0,0 +1,221 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: REST API Gateway to Private ALB and ECS Fargate via VPC Link V2 (uksb-1tthgi812) (tag:apigw-rest-vpclink-pvt-alb-sam) + +Parameters: + VpcId: + Type: AWS::EC2::VPC::Id + Description: VPC ID where resources will be created + + PrivateSubnet1: + Type: AWS::EC2::Subnet::Id + Description: First private subnet ID + + PrivateSubnet2: + Type: AWS::EC2::Subnet::Id + Description: Second private subnet ID + +Resources: + # ALB Security Group + ALBSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupName: rest-api-alb-sg + GroupDescription: Security group for private ALB + VpcId: !Ref VpcId + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + Description: Allow HTTP from anywhere + Tags: + - Key: Name + Value: rest-api-alb-sg + + # ALB to ECS egress rule + ALBToECSEgressRule: + Type: AWS::EC2::SecurityGroupEgress + Properties: + GroupId: !Ref ALBSecurityGroup + IpProtocol: tcp + FromPort: 80 + ToPort: 80 + DestinationSecurityGroupId: !Ref ECSSecurityGroup + Description: Allow traffic to ECS tasks + + # ECS Security Group + ECSSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupName: rest-api-ecs-sg + GroupDescription: Security group for ECS tasks + VpcId: !Ref VpcId + SecurityGroupEgress: + - IpProtocol: -1 + CidrIp: 0.0.0.0/0 + Description: Allow all outbound + Tags: + - Key: Name + Value: rest-api-ecs-sg + + # ECS from ALB ingress rule + ECSFromALBIngressRule: + Type: AWS::EC2::SecurityGroupIngress + Properties: + GroupId: !Ref ECSSecurityGroup + IpProtocol: tcp + FromPort: 80 + ToPort: 80 + SourceSecurityGroupId: !Ref ALBSecurityGroup + Description: Allow traffic from ALB + + # ECS Cluster + ECSCluster: + Type: AWS::ECS::Cluster + Properties: + ClusterName: rest-api-cluster + + # ECS Task Execution Role + ECSTaskExecutionRole: + Type: AWS::IAM::Role + Properties: + RoleName: rest-api-ecs-task-execution-role + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: ecs-tasks.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy + + # ECS Task Role + ECSTaskRole: + Type: AWS::IAM::Role + Properties: + RoleName: rest-api-ecs-task-role + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: ecs-tasks.amazonaws.com + Action: sts:AssumeRole + + # ECS Task Definition + ECSTaskDefinition: + Type: AWS::ECS::TaskDefinition + Properties: + Family: rest-api-task + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + Cpu: '512' + Memory: '1024' + ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn + TaskRoleArn: !GetAtt ECSTaskRole.Arn + ContainerDefinitions: + - Name: web + Image: nginx + Essential: true + PortMappings: + - ContainerPort: 80 + Protocol: tcp + + # Application Load Balancer + PrivateALB: + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + Properties: + Name: rest-api-private-alb + Type: application + Scheme: internal + SecurityGroups: + - !Ref ALBSecurityGroup + Subnets: + - !Ref PrivateSubnet1 + - !Ref PrivateSubnet2 + Tags: + - Key: Name + Value: rest-api-private-alb + + # Target Group + ECSTargetGroup: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + Name: rest-api-ecs-tg + Port: 80 + Protocol: HTTP + VpcId: !Ref VpcId + TargetType: ip + Tags: + - Key: Name + Value: rest-api-ecs-tg + + # ALB Listener + ALBListener: + Type: AWS::ElasticLoadBalancingV2::Listener + Properties: + LoadBalancerArn: !Ref PrivateALB + Port: 80 + Protocol: HTTP + DefaultActions: + - Type: forward + TargetGroupArn: !Ref ECSTargetGroup + + # ECS Service + ECSService: + Type: AWS::ECS::Service + DependsOn: + - ALBListener + Properties: + ServiceName: rest-api-service + Cluster: !Ref ECSCluster + TaskDefinition: !Ref ECSTaskDefinition + DesiredCount: 2 + LaunchType: FARGATE + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 50 + HealthCheckGracePeriodSeconds: 60 + NetworkConfiguration: + AwsvpcConfiguration: + Subnets: + - !Ref PrivateSubnet1 + - !Ref PrivateSubnet2 + SecurityGroups: + - !Ref ECSSecurityGroup + LoadBalancers: + - ContainerName: web + ContainerPort: 80 + TargetGroupArn: !Ref ECSTargetGroup + + # VPC Link V2 + VpcLink: + Type: AWS::ApiGatewayV2::VpcLink + Properties: + Name: rest-api-vpclink-v2 + SubnetIds: + - !Ref PrivateSubnet1 + - !Ref PrivateSubnet2 + + # REST API Gateway using SAM + RestApi: + Type: AWS::Serverless::Api + Properties: + Name: rest-api-vpclink-demo + StageName: prod + Description: REST API with VPC Link V2 to private ALB + EndpointConfiguration: + Type: REGIONAL + DefinitionBody: + Fn::Transform: + Name: AWS::Include + Parameters: + Location: ./api.yaml + +Outputs: + RestApiEndpoint: + Description: REST API Gateway Endpoint URL + Value: !Sub 'https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/prod'