From 67acfc8a6bc5d9bb462f0180dcaee3d6fa36e388 Mon Sep 17 00:00:00 2001 From: Abhishek Agawane Date: Wed, 3 Dec 2025 10:12:29 +0530 Subject: [PATCH 1/9] Add REST API Gateway with VPC Link V2 to Private ALB pattern This pattern demonstrates how to integrate a REST API Gateway with a private Application Load Balancer and ECS Fargate cluster using VPC Link V2. Key features: - REST API Gateway with proxy integration - VPC Link V2 for private integration - Private ALB routing to ECS Fargate - Security groups and IAM roles - Uses existing VPC and subnets --- .../.gitignore | 29 ++ .../README.md | 96 +++++ .../example-pattern.json | 62 ++++ apigw-rest-vpclink-pvt-alb-terraform/main.tf | 333 ++++++++++++++++++ .../outputs.tf | 24 ++ .../variables.tf | 15 + 6 files changed, 559 insertions(+) create mode 100644 apigw-rest-vpclink-pvt-alb-terraform/.gitignore create mode 100644 apigw-rest-vpclink-pvt-alb-terraform/README.md create mode 100644 apigw-rest-vpclink-pvt-alb-terraform/example-pattern.json create mode 100644 apigw-rest-vpclink-pvt-alb-terraform/main.tf create mode 100644 apigw-rest-vpclink-pvt-alb-terraform/outputs.tf create mode 100644 apigw-rest-vpclink-pvt-alb-terraform/variables.tf diff --git a/apigw-rest-vpclink-pvt-alb-terraform/.gitignore b/apigw-rest-vpclink-pvt-alb-terraform/.gitignore new file mode 100644 index 000000000..e4abf1de0 --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-terraform/.gitignore @@ -0,0 +1,29 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files +*.tfvars +*.tfvars.json + +# Ignore override files +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include tfplan files +*tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +# No additional exclusions needed diff --git a/apigw-rest-vpclink-pvt-alb-terraform/README.md b/apigw-rest-vpclink-pvt-alb-terraform/README.md new file mode 100644 index 000000000..42d342c1a --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-terraform/README.md @@ -0,0 +1,96 @@ +# REST API Gateway to Private HTTP Endpoint via VPC Link V2 + +This Terraform template deploys a complete serverless integration pattern connecting a public REST API Gateway to a private ECS Fargate cluster via VPC Link V2. + +### Prerequisites: +* An existing VPC with private subnets +* Private subnets must have internet access (via NAT Gateway or Internet 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 +* VPC Link V2 connecting API Gateway to the private ALB +* REST API Gateway with proxy integration to the ALB + +Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigw-rest-vpclink-pvt-alb-terraform/ + +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 +* [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) 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-terraform + ``` +3. Update the `terraform.tfvars` file with your VPC ID and private subnet IDs: + ```hcl + vpc_id = "vpc-xxxxxxxxx" + + private_subnets = [ + "subnet-xxxxxxxxx", + "subnet-yyyyyyyyy" + ] + ``` +4. Run the below command to initialize, download, and install the defined providers. In case you are not already familiar with the Terraform CLI, refer Terraform [documentation](https://www.terraform.io/cli/commands) to learn more about the various commands. + ``` + terraform init + ``` +5. Deploy the AWS resources for the pattern as specified in the `main.tf` file. Input variables are configured in `variables.tf`. But, there are different ways to pass variables to the CLI. + + Use the below command to review the changes before deploying. + ``` + terraform plan + ``` + Deploy: + ``` + terraform apply --auto-approve + ``` +6. Note the output from the Terraform deployment process. These contain the resource names and/or ARNs which are used for testing. + +## How it works + +This pattern allows integration of public REST API Gateway endpoint to a private Application Load Balancer with an ECS Fargate cluster behind it. It allows to build a secure pattern without exposing the private subnet resources and can be accessed only via a VPC Link V2. + +The integration uses the `--integration-target` parameter with AWS CLI to properly configure the REST API Gateway with VPC Link V2, as this feature is not yet fully supported in the Terraform AWS provider. + +## Testing + +The stack creates and outputs the REST API endpoint. Open a browser and try out the generated API endpoint. You should see the Nginx home page. +Or, run the below command with the appropriate API endpoint. You should get a 200 response code. + +```bash +curl -s -o /dev/null -w "%{http_code}" ; echo +``` + +## Cleanup + +1. Change to the below directory inside the cloned git repo: + ``` + cd serverless-patterns/apigw-rest-vpclink-pvt-alb-terraform + ``` +2. Delete the resources + ```bash + terraform destroy + ``` +3. Enter 'yes' when prompted. + +4. Check if all the resources were deleted successfully. + ```bash + terraform show + ``` +---- +Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 diff --git a/apigw-rest-vpclink-pvt-alb-terraform/example-pattern.json b/apigw-rest-vpclink-pvt-alb-terraform/example-pattern.json new file mode 100644 index 000000000..fa37a34f4 --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-terraform/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": "HCL", + "level": "200", + "framework": "Terraform", + "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-terraform", + "templateURL": "serverless-patterns/apigw-rest-vpclink-pvt-alb-terraform", + "projectFolder": "apigw-rest-vpclink-pvt-alb-terraform", + "templateFile": "apigw-rest-vpclink-pvt-alb-terraform/main.tf" + } + }, + "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": [ + "terraform init && terraform apply" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "terraform destroy" + ] + }, + "authors": [ + { + "name": "Abhishek Agawane", + "image": "https://drive.google.com/file/d/1E-5koDaKEaMUtOctX32I9TLwfh3kgpAq/view?usp=drivesdk", + "bio": "I am a Cloud Support Engineer (Serverless) at AWS who loves cloud computing", + "linkedin": "https://www.linkedin.com/in/agawabhi/" + } + ] +} diff --git a/apigw-rest-vpclink-pvt-alb-terraform/main.tf b/apigw-rest-vpclink-pvt-alb-terraform/main.tf new file mode 100644 index 000000000..b06177a57 --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-terraform/main.tf @@ -0,0 +1,333 @@ +# Required providers configuration +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.80" + } + } + required_version = ">= 1.9" +} + +provider "aws" { + profile = "default" + region = var.aws_region +} + +############################################## +# PART 1: Private ALB with ECS Fargate Target +############################################## + +# ALB security group +resource "aws_security_group" "alb_sg" { + name = "rest-api-alb-sg" + description = "Security group for private ALB" + vpc_id = var.vpc_id + + ingress { + description = "Allow HTTP from anywhere" + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = { + Name = "rest-api-alb-sg" + } +} + +# ALB egress rule to ECS +resource "aws_security_group_rule" "alb_to_ecs" { + type = "egress" + description = "Allow traffic to ECS tasks" + from_port = 80 + to_port = 80 + protocol = "tcp" + security_group_id = aws_security_group.alb_sg.id + source_security_group_id = aws_security_group.ecs_sg.id +} + +# ECS task security group +resource "aws_security_group" "ecs_sg" { + name = "rest-api-ecs-sg" + description = "Security group for ECS tasks" + vpc_id = var.vpc_id + + egress { + description = "Allow all outbound" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = { + Name = "rest-api-ecs-sg" + } +} + +# ECS ingress rule from ALB +resource "aws_security_group_rule" "ecs_from_alb" { + type = "ingress" + description = "Allow traffic from ALB" + from_port = 80 + to_port = 80 + protocol = "tcp" + security_group_id = aws_security_group.ecs_sg.id + source_security_group_id = aws_security_group.alb_sg.id +} + +# ECS Cluster +resource "aws_ecs_cluster" "main" { + name = "rest-api-cluster" + + tags = { + Name = "rest-api-cluster" + } +} + +# ECS Task Execution Role +resource "aws_iam_role" "ecs_task_execution_role" { + name = "rest-api-ecs-task-execution-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "ecs-tasks.amazonaws.com" + } + } + ] + }) +} + +resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" { + role = aws_iam_role.ecs_task_execution_role.name + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" +} + +# ECS Task Role +resource "aws_iam_role" "ecs_task_role" { + name = "rest-api-ecs-task-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "ecs-tasks.amazonaws.com" + } + } + ] + }) +} + +# ECS Task Definition +resource "aws_ecs_task_definition" "app" { + family = "rest-api-task" + network_mode = "awsvpc" + requires_compatibilities = ["FARGATE"] + cpu = "512" + memory = "1024" + execution_role_arn = aws_iam_role.ecs_task_execution_role.arn + task_role_arn = aws_iam_role.ecs_task_role.arn + + container_definitions = jsonencode([ + { + name = "web" + image = "nginx" + essential = true + portMappings = [ + { + containerPort = 80 + protocol = "tcp" + } + ] + } + ]) + + tags = { + Name = "rest-api-task" + } +} + +# ECS Service +resource "aws_ecs_service" "app" { + name = "rest-api-service" + cluster = aws_ecs_cluster.main.id + task_definition = aws_ecs_task_definition.app.arn + desired_count = 2 + deployment_maximum_percent = 200 + deployment_minimum_healthy_percent = 50 + enable_ecs_managed_tags = false + health_check_grace_period_seconds = 60 + launch_type = "FARGATE" + + network_configuration { + subnets = var.private_subnets + security_groups = [aws_security_group.ecs_sg.id] + } + + load_balancer { + target_group_arn = aws_lb_target_group.ecs_tg.arn + container_name = "web" + container_port = 80 + } + + depends_on = [aws_lb_target_group.ecs_tg, aws_lb_listener.http] + + tags = { + Name = "rest-api-service" + } +} + +# Create private Application Load Balancer +resource "aws_lb" "private_alb" { + name = "rest-api-private-alb" + internal = true + load_balancer_type = "application" + security_groups = [aws_security_group.alb_sg.id] + subnets = var.private_subnets + + tags = { + Name = "rest-api-private-alb" + } +} + +# Create target group for ECS +resource "aws_lb_target_group" "ecs_tg" { + name = "rest-api-ecs-tg" + port = 80 + protocol = "HTTP" + vpc_id = var.vpc_id + target_type = "ip" + + tags = { + Name = "rest-api-ecs-tg" + } +} + +# Create ALB listener +resource "aws_lb_listener" "http" { + load_balancer_arn = aws_lb.private_alb.arn + port = "80" + protocol = "HTTP" + + default_action { + type = "forward" + target_group_arn = aws_lb_target_group.ecs_tg.arn + } +} + +############################################## +# PART 2: VPC Link V2 +############################################## + +resource "aws_apigatewayv2_vpc_link" "vpclink" { + name = "rest-api-vpclink-v2" + security_group_ids = [] + subnet_ids = var.private_subnets + + tags = { + Name = "rest-api-vpclink-v2" + } +} + +############################################## +# PART 3: REST API with VPC Link Integration +############################################## + +# Create REST API +resource "aws_api_gateway_rest_api" "rest_api" { + name = "rest-api-vpclink-demo" + description = "REST API with VPC Link V2 to private ALB" + + endpoint_configuration { + types = ["REGIONAL"] + } +} + +# Create proxy resource +resource "aws_api_gateway_resource" "proxy" { + rest_api_id = aws_api_gateway_rest_api.rest_api.id + parent_id = aws_api_gateway_rest_api.rest_api.root_resource_id + path_part = "{proxy+}" +} + +# Create ANY method +resource "aws_api_gateway_method" "proxy_any" { + rest_api_id = aws_api_gateway_rest_api.rest_api.id + resource_id = aws_api_gateway_resource.proxy.id + http_method = "ANY" + authorization = "NONE" + + request_parameters = { + "method.request.path.proxy" = true + } +} + +# Create VPC Link integration with VPC Link V2 +# Note: REST API + VPC Link V2 integration requires using AWS CLI directly +# as Terraform AWS provider doesn't fully support the integration_target parameter yet +resource "null_resource" "vpclink_integration" { + triggers = { + rest_api_id = aws_api_gateway_rest_api.rest_api.id + resource_id = aws_api_gateway_resource.proxy.id + vpc_link_id = aws_apigatewayv2_vpc_link.vpclink.id + alb_arn = aws_lb.private_alb.arn + } + + provisioner "local-exec" { + command = <<-EOT + aws apigateway put-integration \ + --rest-api-id ${aws_api_gateway_rest_api.rest_api.id} \ + --resource-id ${aws_api_gateway_resource.proxy.id} \ + --http-method ANY \ + --type HTTP_PROXY \ + --integration-http-method ANY \ + --connection-type VPC_LINK \ + --connection-id ${aws_apigatewayv2_vpc_link.vpclink.id} \ + --integration-target ${aws_lb.private_alb.arn} \ + --uri http://${aws_lb.private_alb.dns_name}/{proxy} \ + --request-parameters '{"integration.request.path.proxy":"method.request.path.proxy"}' + EOT + } + + depends_on = [ + aws_apigatewayv2_vpc_link.vpclink, + aws_lb_listener.http, + aws_api_gateway_method.proxy_any + ] +} + +# Create deployment +resource "aws_api_gateway_deployment" "deployment" { + rest_api_id = aws_api_gateway_rest_api.rest_api.id + + triggers = { + redeployment = sha1(jsonencode([ + aws_api_gateway_resource.proxy.id, + aws_api_gateway_method.proxy_any.id, + null_resource.vpclink_integration.id, + ])) + } + + lifecycle { + create_before_destroy = true + } + + depends_on = [null_resource.vpclink_integration] +} + +# Create stage +resource "aws_api_gateway_stage" "prod" { + deployment_id = aws_api_gateway_deployment.deployment.id + rest_api_id = aws_api_gateway_rest_api.rest_api.id + stage_name = "prod" +} diff --git a/apigw-rest-vpclink-pvt-alb-terraform/outputs.tf b/apigw-rest-vpclink-pvt-alb-terraform/outputs.tf new file mode 100644 index 000000000..a093b6c21 --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-terraform/outputs.tf @@ -0,0 +1,24 @@ +output "rest_api_endpoint" { + value = aws_api_gateway_stage.prod.invoke_url + description = "REST API Gateway Endpoint URL" +} + +output "vpc_link_id" { + value = aws_apigatewayv2_vpc_link.vpclink.id + description = "VPC Link V2 ID" +} + +output "alb_dns_name" { + value = aws_lb.private_alb.dns_name + description = "Private ALB DNS name" +} + +output "ecs_cluster_name" { + value = aws_ecs_cluster.main.name + description = "ECS cluster name" +} + +output "ecs_service_name" { + value = aws_ecs_service.app.name + description = "ECS service name" +} diff --git a/apigw-rest-vpclink-pvt-alb-terraform/variables.tf b/apigw-rest-vpclink-pvt-alb-terraform/variables.tf new file mode 100644 index 000000000..50a46d5b8 --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-terraform/variables.tf @@ -0,0 +1,15 @@ +variable "aws_region" { + description = "AWS region" + type = string + default = "us-east-1" +} + +variable "vpc_id" { + description = "VPC ID where resources will be created" + type = string +} + +variable "private_subnets" { + description = "List of private subnet IDs" + type = list(string) +} From f86f6c8db1dcaaf5115895f156d261ad28ff4787 Mon Sep 17 00:00:00 2001 From: Abhishek Agawane Date: Wed, 3 Dec 2025 10:26:26 +0530 Subject: [PATCH 2/9] Add REST API Gateway with VPC Link V2 to Private ALB pattern (SAM) This pattern demonstrates how to integrate a REST API Gateway with a private Application Load Balancer and ECS Fargate cluster using VPC Link V2. Key features: - REST API Gateway with proxy integration - VPC Link V2 for private integration - Private ALB routing to ECS Fargate - Security groups and IAM roles - AWS SAM implementation - Uses existing VPC and subnets --- apigw-rest-vpclink-pvt-alb-sam/.gitignore | 39 +++ apigw-rest-vpclink-pvt-alb-sam/README.md | 82 ++++++ .../example-pattern.json | 62 ++++ apigw-rest-vpclink-pvt-alb-sam/template.yaml | 275 ++++++++++++++++++ 4 files changed, 458 insertions(+) create mode 100644 apigw-rest-vpclink-pvt-alb-sam/.gitignore create mode 100644 apigw-rest-vpclink-pvt-alb-sam/README.md create mode 100644 apigw-rest-vpclink-pvt-alb-sam/example-pattern.json create mode 100644 apigw-rest-vpclink-pvt-alb-sam/template.yaml 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..daa876d80 --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-sam/README.md @@ -0,0 +1,82 @@ +# REST API Gateway to Private HTTP Endpoint via VPC Link V2 + +This AWS SAM template deploys the following resources. It requires a VPC id and private subnet ids as inputs. It is assumed that the VPC and subnets already exist and are configured with the required network routes (internet gateway for private subnets to pull container images). + +### Prerequisites: +* An existing VPC with private subnets +* Private subnets must have internet access (via NAT Gateway or Internet 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 +* VPC Link V2 connecting API Gateway to the private ALB +* REST API Gateway 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 + ``` +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 allows integration of public REST API Gateway endpoint to a private Application Load Balancer with an ECS Fargate cluster behind it. It allows to build a secure pattern without exposing the private subnet resources and can be accessed only via a VPC Link V2. + +The integration uses CloudFormation's native support for VPC Link V2 with REST API Gateway. + +## Testing + +The stack creates and outputs the REST API endpoint. Open a browser and try out the generated API endpoint. You should see the Nginx home page. +Or, run the below command with the appropriate API endpoint. You should get a 200 response code. + +```bash +curl -s -o /dev/null -w "%{http_code}" ; echo +``` + +## 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 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 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..25b953747 --- /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": "I am a Cloud Support Engineer (Serverless) at AWS who loves cloud computing", + "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..004937c3a --- /dev/null +++ b/apigw-rest-vpclink-pvt-alb-sam/template.yaml @@ -0,0 +1,275 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: REST API Gateway to Private ALB and ECS Fargate via VPC Link V2 + +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 + RestApi: + Type: AWS::ApiGateway::RestApi + Properties: + Name: rest-api-vpclink-demo + Description: REST API with VPC Link V2 to private ALB + EndpointConfiguration: + Types: + - REGIONAL + + # API Gateway Resource (proxy) + ProxyResource: + Type: AWS::ApiGateway::Resource + Properties: + RestApiId: !Ref RestApi + ParentId: !GetAtt RestApi.RootResourceId + PathPart: '{proxy+}' + + # API Gateway Method (ANY) + ProxyMethod: + Type: AWS::ApiGateway::Method + Properties: + RestApiId: !Ref RestApi + ResourceId: !Ref ProxyResource + HttpMethod: ANY + AuthorizationType: NONE + RequestParameters: + method.request.path.proxy: true + Integration: + Type: HTTP_PROXY + IntegrationHttpMethod: ANY + Uri: !Sub 'http://${PrivateALB.DNSName}/{proxy}' + ConnectionType: VPC_LINK + ConnectionId: !Ref VpcLink + RequestParameters: + integration.request.path.proxy: method.request.path.proxy + + # API Gateway Deployment + ApiDeployment: + Type: AWS::ApiGateway::Deployment + DependsOn: + - ProxyMethod + Properties: + RestApiId: !Ref RestApi + + # API Gateway Stage + ApiStage: + Type: AWS::ApiGateway::Stage + Properties: + RestApiId: !Ref RestApi + DeploymentId: !Ref ApiDeployment + StageName: prod + +Outputs: + RestApiEndpoint: + Description: REST API Gateway Endpoint URL + Value: !Sub 'https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/prod' + + VpcLinkId: + Description: VPC Link V2 ID + Value: !Ref VpcLink + + ALBDnsName: + Description: Private ALB DNS name + Value: !GetAtt PrivateALB.DNSName + + ECSClusterName: + Description: ECS cluster name + Value: !Ref ECSCluster + + ECSServiceName: + Description: ECS service name + Value: !GetAtt ECSService.Name From 4a2f7f8ac098c592251d70d27ce7ff2e6afe2400 Mon Sep 17 00:00:00 2001 From: Abhishek Agawane Date: Wed, 3 Dec 2025 12:47:44 +0530 Subject: [PATCH 3/9] Update author bio in SAM pattern --- apigw-rest-vpclink-pvt-alb-sam/example-pattern.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apigw-rest-vpclink-pvt-alb-sam/example-pattern.json b/apigw-rest-vpclink-pvt-alb-sam/example-pattern.json index 25b953747..567f9b39e 100644 --- a/apigw-rest-vpclink-pvt-alb-sam/example-pattern.json +++ b/apigw-rest-vpclink-pvt-alb-sam/example-pattern.json @@ -55,7 +55,7 @@ { "name": "Abhishek Agawane", "image": "https://drive.google.com/file/d/1E-5koDaKEaMUtOctX32I9TLwfh3kgpAq/view?usp=drivesdk", - "bio": "I am a Cloud Support Engineer (Serverless) at AWS who loves cloud computing", + "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/" } ] From ac82347358e6bb7d3a4d470abe5271792321cd8d Mon Sep 17 00:00:00 2001 From: Abhishek Agawane Date: Mon, 22 Dec 2025 13:00:28 +0530 Subject: [PATCH 4/9] Remove Terraform implementation from SAM pattern branch The Terraform implementation is in a separate branch/PR. This branch should only contain the SAM implementation of the apigw-rest-vpclink-pvt-alb pattern. --- .../.gitignore | 29 -- .../README.md | 96 ----- .../example-pattern.json | 62 ---- apigw-rest-vpclink-pvt-alb-terraform/main.tf | 333 ------------------ .../outputs.tf | 24 -- .../variables.tf | 15 - 6 files changed, 559 deletions(-) delete mode 100644 apigw-rest-vpclink-pvt-alb-terraform/.gitignore delete mode 100644 apigw-rest-vpclink-pvt-alb-terraform/README.md delete mode 100644 apigw-rest-vpclink-pvt-alb-terraform/example-pattern.json delete mode 100644 apigw-rest-vpclink-pvt-alb-terraform/main.tf delete mode 100644 apigw-rest-vpclink-pvt-alb-terraform/outputs.tf delete mode 100644 apigw-rest-vpclink-pvt-alb-terraform/variables.tf diff --git a/apigw-rest-vpclink-pvt-alb-terraform/.gitignore b/apigw-rest-vpclink-pvt-alb-terraform/.gitignore deleted file mode 100644 index e4abf1de0..000000000 --- a/apigw-rest-vpclink-pvt-alb-terraform/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# Local .terraform directories -**/.terraform/* - -# .tfstate files -*.tfstate -*.tfstate.* - -# Crash log files -crash.log -crash.*.log - -# Exclude all .tfvars files -*.tfvars -*.tfvars.json - -# Ignore override files -override.tf -override.tf.json -*_override.tf -*_override.tf.json - -# Include tfplan files -*tfplan* - -# Ignore CLI configuration files -.terraformrc -terraform.rc - -# No additional exclusions needed diff --git a/apigw-rest-vpclink-pvt-alb-terraform/README.md b/apigw-rest-vpclink-pvt-alb-terraform/README.md deleted file mode 100644 index 42d342c1a..000000000 --- a/apigw-rest-vpclink-pvt-alb-terraform/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# REST API Gateway to Private HTTP Endpoint via VPC Link V2 - -This Terraform template deploys a complete serverless integration pattern connecting a public REST API Gateway to a private ECS Fargate cluster via VPC Link V2. - -### Prerequisites: -* An existing VPC with private subnets -* Private subnets must have internet access (via NAT Gateway or Internet 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 -* VPC Link V2 connecting API Gateway to the private ALB -* REST API Gateway with proxy integration to the ALB - -Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigw-rest-vpclink-pvt-alb-terraform/ - -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 -* [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) 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-terraform - ``` -3. Update the `terraform.tfvars` file with your VPC ID and private subnet IDs: - ```hcl - vpc_id = "vpc-xxxxxxxxx" - - private_subnets = [ - "subnet-xxxxxxxxx", - "subnet-yyyyyyyyy" - ] - ``` -4. Run the below command to initialize, download, and install the defined providers. In case you are not already familiar with the Terraform CLI, refer Terraform [documentation](https://www.terraform.io/cli/commands) to learn more about the various commands. - ``` - terraform init - ``` -5. Deploy the AWS resources for the pattern as specified in the `main.tf` file. Input variables are configured in `variables.tf`. But, there are different ways to pass variables to the CLI. - - Use the below command to review the changes before deploying. - ``` - terraform plan - ``` - Deploy: - ``` - terraform apply --auto-approve - ``` -6. Note the output from the Terraform deployment process. These contain the resource names and/or ARNs which are used for testing. - -## How it works - -This pattern allows integration of public REST API Gateway endpoint to a private Application Load Balancer with an ECS Fargate cluster behind it. It allows to build a secure pattern without exposing the private subnet resources and can be accessed only via a VPC Link V2. - -The integration uses the `--integration-target` parameter with AWS CLI to properly configure the REST API Gateway with VPC Link V2, as this feature is not yet fully supported in the Terraform AWS provider. - -## Testing - -The stack creates and outputs the REST API endpoint. Open a browser and try out the generated API endpoint. You should see the Nginx home page. -Or, run the below command with the appropriate API endpoint. You should get a 200 response code. - -```bash -curl -s -o /dev/null -w "%{http_code}" ; echo -``` - -## Cleanup - -1. Change to the below directory inside the cloned git repo: - ``` - cd serverless-patterns/apigw-rest-vpclink-pvt-alb-terraform - ``` -2. Delete the resources - ```bash - terraform destroy - ``` -3. Enter 'yes' when prompted. - -4. Check if all the resources were deleted successfully. - ```bash - terraform show - ``` ----- -Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - -SPDX-License-Identifier: MIT-0 diff --git a/apigw-rest-vpclink-pvt-alb-terraform/example-pattern.json b/apigw-rest-vpclink-pvt-alb-terraform/example-pattern.json deleted file mode 100644 index fa37a34f4..000000000 --- a/apigw-rest-vpclink-pvt-alb-terraform/example-pattern.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "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": "HCL", - "level": "200", - "framework": "Terraform", - "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-terraform", - "templateURL": "serverless-patterns/apigw-rest-vpclink-pvt-alb-terraform", - "projectFolder": "apigw-rest-vpclink-pvt-alb-terraform", - "templateFile": "apigw-rest-vpclink-pvt-alb-terraform/main.tf" - } - }, - "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": [ - "terraform init && terraform apply" - ] - }, - "testing": { - "text": [ - "See the GitHub repo for detailed testing instructions." - ] - }, - "cleanup": { - "text": [ - "terraform destroy" - ] - }, - "authors": [ - { - "name": "Abhishek Agawane", - "image": "https://drive.google.com/file/d/1E-5koDaKEaMUtOctX32I9TLwfh3kgpAq/view?usp=drivesdk", - "bio": "I am a Cloud Support Engineer (Serverless) at AWS who loves cloud computing", - "linkedin": "https://www.linkedin.com/in/agawabhi/" - } - ] -} diff --git a/apigw-rest-vpclink-pvt-alb-terraform/main.tf b/apigw-rest-vpclink-pvt-alb-terraform/main.tf deleted file mode 100644 index b06177a57..000000000 --- a/apigw-rest-vpclink-pvt-alb-terraform/main.tf +++ /dev/null @@ -1,333 +0,0 @@ -# Required providers configuration -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.80" - } - } - required_version = ">= 1.9" -} - -provider "aws" { - profile = "default" - region = var.aws_region -} - -############################################## -# PART 1: Private ALB with ECS Fargate Target -############################################## - -# ALB security group -resource "aws_security_group" "alb_sg" { - name = "rest-api-alb-sg" - description = "Security group for private ALB" - vpc_id = var.vpc_id - - ingress { - description = "Allow HTTP from anywhere" - from_port = 80 - to_port = 80 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "rest-api-alb-sg" - } -} - -# ALB egress rule to ECS -resource "aws_security_group_rule" "alb_to_ecs" { - type = "egress" - description = "Allow traffic to ECS tasks" - from_port = 80 - to_port = 80 - protocol = "tcp" - security_group_id = aws_security_group.alb_sg.id - source_security_group_id = aws_security_group.ecs_sg.id -} - -# ECS task security group -resource "aws_security_group" "ecs_sg" { - name = "rest-api-ecs-sg" - description = "Security group for ECS tasks" - vpc_id = var.vpc_id - - egress { - description = "Allow all outbound" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "rest-api-ecs-sg" - } -} - -# ECS ingress rule from ALB -resource "aws_security_group_rule" "ecs_from_alb" { - type = "ingress" - description = "Allow traffic from ALB" - from_port = 80 - to_port = 80 - protocol = "tcp" - security_group_id = aws_security_group.ecs_sg.id - source_security_group_id = aws_security_group.alb_sg.id -} - -# ECS Cluster -resource "aws_ecs_cluster" "main" { - name = "rest-api-cluster" - - tags = { - Name = "rest-api-cluster" - } -} - -# ECS Task Execution Role -resource "aws_iam_role" "ecs_task_execution_role" { - name = "rest-api-ecs-task-execution-role" - - assume_role_policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Action = "sts:AssumeRole" - Effect = "Allow" - Principal = { - Service = "ecs-tasks.amazonaws.com" - } - } - ] - }) -} - -resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" { - role = aws_iam_role.ecs_task_execution_role.name - policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" -} - -# ECS Task Role -resource "aws_iam_role" "ecs_task_role" { - name = "rest-api-ecs-task-role" - - assume_role_policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Action = "sts:AssumeRole" - Effect = "Allow" - Principal = { - Service = "ecs-tasks.amazonaws.com" - } - } - ] - }) -} - -# ECS Task Definition -resource "aws_ecs_task_definition" "app" { - family = "rest-api-task" - network_mode = "awsvpc" - requires_compatibilities = ["FARGATE"] - cpu = "512" - memory = "1024" - execution_role_arn = aws_iam_role.ecs_task_execution_role.arn - task_role_arn = aws_iam_role.ecs_task_role.arn - - container_definitions = jsonencode([ - { - name = "web" - image = "nginx" - essential = true - portMappings = [ - { - containerPort = 80 - protocol = "tcp" - } - ] - } - ]) - - tags = { - Name = "rest-api-task" - } -} - -# ECS Service -resource "aws_ecs_service" "app" { - name = "rest-api-service" - cluster = aws_ecs_cluster.main.id - task_definition = aws_ecs_task_definition.app.arn - desired_count = 2 - deployment_maximum_percent = 200 - deployment_minimum_healthy_percent = 50 - enable_ecs_managed_tags = false - health_check_grace_period_seconds = 60 - launch_type = "FARGATE" - - network_configuration { - subnets = var.private_subnets - security_groups = [aws_security_group.ecs_sg.id] - } - - load_balancer { - target_group_arn = aws_lb_target_group.ecs_tg.arn - container_name = "web" - container_port = 80 - } - - depends_on = [aws_lb_target_group.ecs_tg, aws_lb_listener.http] - - tags = { - Name = "rest-api-service" - } -} - -# Create private Application Load Balancer -resource "aws_lb" "private_alb" { - name = "rest-api-private-alb" - internal = true - load_balancer_type = "application" - security_groups = [aws_security_group.alb_sg.id] - subnets = var.private_subnets - - tags = { - Name = "rest-api-private-alb" - } -} - -# Create target group for ECS -resource "aws_lb_target_group" "ecs_tg" { - name = "rest-api-ecs-tg" - port = 80 - protocol = "HTTP" - vpc_id = var.vpc_id - target_type = "ip" - - tags = { - Name = "rest-api-ecs-tg" - } -} - -# Create ALB listener -resource "aws_lb_listener" "http" { - load_balancer_arn = aws_lb.private_alb.arn - port = "80" - protocol = "HTTP" - - default_action { - type = "forward" - target_group_arn = aws_lb_target_group.ecs_tg.arn - } -} - -############################################## -# PART 2: VPC Link V2 -############################################## - -resource "aws_apigatewayv2_vpc_link" "vpclink" { - name = "rest-api-vpclink-v2" - security_group_ids = [] - subnet_ids = var.private_subnets - - tags = { - Name = "rest-api-vpclink-v2" - } -} - -############################################## -# PART 3: REST API with VPC Link Integration -############################################## - -# Create REST API -resource "aws_api_gateway_rest_api" "rest_api" { - name = "rest-api-vpclink-demo" - description = "REST API with VPC Link V2 to private ALB" - - endpoint_configuration { - types = ["REGIONAL"] - } -} - -# Create proxy resource -resource "aws_api_gateway_resource" "proxy" { - rest_api_id = aws_api_gateway_rest_api.rest_api.id - parent_id = aws_api_gateway_rest_api.rest_api.root_resource_id - path_part = "{proxy+}" -} - -# Create ANY method -resource "aws_api_gateway_method" "proxy_any" { - rest_api_id = aws_api_gateway_rest_api.rest_api.id - resource_id = aws_api_gateway_resource.proxy.id - http_method = "ANY" - authorization = "NONE" - - request_parameters = { - "method.request.path.proxy" = true - } -} - -# Create VPC Link integration with VPC Link V2 -# Note: REST API + VPC Link V2 integration requires using AWS CLI directly -# as Terraform AWS provider doesn't fully support the integration_target parameter yet -resource "null_resource" "vpclink_integration" { - triggers = { - rest_api_id = aws_api_gateway_rest_api.rest_api.id - resource_id = aws_api_gateway_resource.proxy.id - vpc_link_id = aws_apigatewayv2_vpc_link.vpclink.id - alb_arn = aws_lb.private_alb.arn - } - - provisioner "local-exec" { - command = <<-EOT - aws apigateway put-integration \ - --rest-api-id ${aws_api_gateway_rest_api.rest_api.id} \ - --resource-id ${aws_api_gateway_resource.proxy.id} \ - --http-method ANY \ - --type HTTP_PROXY \ - --integration-http-method ANY \ - --connection-type VPC_LINK \ - --connection-id ${aws_apigatewayv2_vpc_link.vpclink.id} \ - --integration-target ${aws_lb.private_alb.arn} \ - --uri http://${aws_lb.private_alb.dns_name}/{proxy} \ - --request-parameters '{"integration.request.path.proxy":"method.request.path.proxy"}' - EOT - } - - depends_on = [ - aws_apigatewayv2_vpc_link.vpclink, - aws_lb_listener.http, - aws_api_gateway_method.proxy_any - ] -} - -# Create deployment -resource "aws_api_gateway_deployment" "deployment" { - rest_api_id = aws_api_gateway_rest_api.rest_api.id - - triggers = { - redeployment = sha1(jsonencode([ - aws_api_gateway_resource.proxy.id, - aws_api_gateway_method.proxy_any.id, - null_resource.vpclink_integration.id, - ])) - } - - lifecycle { - create_before_destroy = true - } - - depends_on = [null_resource.vpclink_integration] -} - -# Create stage -resource "aws_api_gateway_stage" "prod" { - deployment_id = aws_api_gateway_deployment.deployment.id - rest_api_id = aws_api_gateway_rest_api.rest_api.id - stage_name = "prod" -} diff --git a/apigw-rest-vpclink-pvt-alb-terraform/outputs.tf b/apigw-rest-vpclink-pvt-alb-terraform/outputs.tf deleted file mode 100644 index a093b6c21..000000000 --- a/apigw-rest-vpclink-pvt-alb-terraform/outputs.tf +++ /dev/null @@ -1,24 +0,0 @@ -output "rest_api_endpoint" { - value = aws_api_gateway_stage.prod.invoke_url - description = "REST API Gateway Endpoint URL" -} - -output "vpc_link_id" { - value = aws_apigatewayv2_vpc_link.vpclink.id - description = "VPC Link V2 ID" -} - -output "alb_dns_name" { - value = aws_lb.private_alb.dns_name - description = "Private ALB DNS name" -} - -output "ecs_cluster_name" { - value = aws_ecs_cluster.main.name - description = "ECS cluster name" -} - -output "ecs_service_name" { - value = aws_ecs_service.app.name - description = "ECS service name" -} diff --git a/apigw-rest-vpclink-pvt-alb-terraform/variables.tf b/apigw-rest-vpclink-pvt-alb-terraform/variables.tf deleted file mode 100644 index 50a46d5b8..000000000 --- a/apigw-rest-vpclink-pvt-alb-terraform/variables.tf +++ /dev/null @@ -1,15 +0,0 @@ -variable "aws_region" { - description = "AWS region" - type = string - default = "us-east-1" -} - -variable "vpc_id" { - description = "VPC ID where resources will be created" - type = string -} - -variable "private_subnets" { - description = "List of private subnet IDs" - type = list(string) -} From bd7dd0943178fd7d19a03f93d1648df6f57e34d1 Mon Sep 17 00:00:00 2001 From: Abhishek Agawane Date: Tue, 6 Jan 2026 11:10:59 +0530 Subject: [PATCH 5/9] Convert to SAM resources and add OpenAPI definition - Replace CloudFormation API Gateway resources with AWS::Serverless::Api - Add external OpenAPI definition file (api.yaml) with AWS::Include transform - Add integrationTarget parameter for VPC Link V2 to ALB integration - Update README to document SAM resource usage and OpenAPI file - Update testing instructions with correct path examples - Update copyright year to 2025 - Tested and validated: API Gateway -> VPC Link V2 -> Internal ALB -> ECS working correctly --- apigw-rest-vpclink-pvt-alb-sam/README.md | 25 +++++--- apigw-rest-vpclink-pvt-alb-sam/api.yaml | 26 +++++++++ apigw-rest-vpclink-pvt-alb-sam/template.yaml | 60 +++++--------------- 3 files changed, 55 insertions(+), 56 deletions(-) create mode 100644 apigw-rest-vpclink-pvt-alb-sam/api.yaml diff --git a/apigw-rest-vpclink-pvt-alb-sam/README.md b/apigw-rest-vpclink-pvt-alb-sam/README.md index daa876d80..9ef3f91d0 100644 --- a/apigw-rest-vpclink-pvt-alb-sam/README.md +++ b/apigw-rest-vpclink-pvt-alb-sam/README.md @@ -1,17 +1,17 @@ # REST API Gateway to Private HTTP Endpoint via VPC Link V2 -This AWS SAM template deploys the following resources. It requires a VPC id and private subnet ids as inputs. It is assumed that the VPC and subnets already exist and are configured with the required network routes (internet gateway for private subnets to pull container images). +This AWS SAM template deploys a REST API Gateway with VPC Link V2 integration to a private Application Load Balancer and 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 or Internet Gateway) to pull container images from Docker Hub +* 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 * VPC Link V2 connecting API Gateway to the private ALB -* REST API Gateway with proxy integration to the ALB +* REST API Gateway (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/ @@ -53,19 +53,26 @@ Important: this application uses various AWS services and there are costs associ ## How it works -This pattern allows integration of public REST API Gateway endpoint to a private Application Load Balancer with an ECS Fargate cluster behind it. It allows to build a secure pattern without exposing the private subnet resources and can be accessed only via a VPC Link V2. +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. -The integration uses CloudFormation's native support for VPC Link V2 with REST API Gateway. +Traffic flows through 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 creates and outputs the REST API endpoint. Open a browser and try out the generated API endpoint. You should see the Nginx home page. -Or, run the below command with the appropriate API endpoint. You should get a 200 response code. +The stack outputs the REST API endpoint. Test it by accessing any path through the API: ```bash -curl -s -o /dev/null -w "%{http_code}" ; echo +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: @@ -77,6 +84,6 @@ curl -s -o /dev/null -w "%{http_code}" ; echo aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus" ``` ---- -Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Copyright 2025 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/template.yaml b/apigw-rest-vpclink-pvt-alb-sam/template.yaml index 004937c3a..c60e43494 100644 --- a/apigw-rest-vpclink-pvt-alb-sam/template.yaml +++ b/apigw-rest-vpclink-pvt-alb-sam/template.yaml @@ -200,64 +200,30 @@ Resources: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 - # REST API Gateway + # REST API Gateway using SAM RestApi: - Type: AWS::ApiGateway::RestApi + Type: AWS::Serverless::Api Properties: Name: rest-api-vpclink-demo + StageName: prod Description: REST API with VPC Link V2 to private ALB EndpointConfiguration: - Types: - - REGIONAL - - # API Gateway Resource (proxy) - ProxyResource: - Type: AWS::ApiGateway::Resource - Properties: - RestApiId: !Ref RestApi - ParentId: !GetAtt RestApi.RootResourceId - PathPart: '{proxy+}' - - # API Gateway Method (ANY) - ProxyMethod: - Type: AWS::ApiGateway::Method - Properties: - RestApiId: !Ref RestApi - ResourceId: !Ref ProxyResource - HttpMethod: ANY - AuthorizationType: NONE - RequestParameters: - method.request.path.proxy: true - Integration: - Type: HTTP_PROXY - IntegrationHttpMethod: ANY - Uri: !Sub 'http://${PrivateALB.DNSName}/{proxy}' - ConnectionType: VPC_LINK - ConnectionId: !Ref VpcLink - RequestParameters: - integration.request.path.proxy: method.request.path.proxy - - # API Gateway Deployment - ApiDeployment: - Type: AWS::ApiGateway::Deployment - DependsOn: - - ProxyMethod - Properties: - RestApiId: !Ref RestApi - - # API Gateway Stage - ApiStage: - Type: AWS::ApiGateway::Stage - Properties: - RestApiId: !Ref RestApi - DeploymentId: !Ref ApiDeployment - StageName: prod + 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' + RestApiId: + Description: REST API Gateway ID + Value: !Ref RestApi + VpcLinkId: Description: VPC Link V2 ID Value: !Ref VpcLink From 796b9104eeb051c3134e57471ba220f9fbb61785 Mon Sep 17 00:00:00 2001 From: Abhishek Agawane Date: Wed, 7 Jan 2026 12:08:25 +0530 Subject: [PATCH 6/9] Address PR feedback: improve documentation and simplify outputs - Use full AWS service names throughout (Amazon API Gateway, Amazon VPC Link V2, Amazon Application Load Balancer, Amazon ECS) - Add problem statement explaining VPC Link V2 eliminates NLB requirement - Add --capabilities CAPABILITY_NAMED_IAM flag to deployment command - Simplify outputs to only include REST API endpoint URL - Update copyright year to 2026 --- apigw-rest-vpclink-pvt-alb-sam/README.md | 14 ++++++++------ apigw-rest-vpclink-pvt-alb-sam/template.yaml | 20 -------------------- 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/apigw-rest-vpclink-pvt-alb-sam/README.md b/apigw-rest-vpclink-pvt-alb-sam/README.md index 9ef3f91d0..f58654f87 100644 --- a/apigw-rest-vpclink-pvt-alb-sam/README.md +++ b/apigw-rest-vpclink-pvt-alb-sam/README.md @@ -1,6 +1,8 @@ -# REST API Gateway to Private HTTP Endpoint via VPC Link V2 +# REST Amazon API Gateway to Private HTTP Endpoint via Amazon VPC Link V2 -This AWS SAM template deploys a REST API Gateway with VPC Link V2 integration to a private Application Load Balancer and ECS Fargate cluster. The API definition is provided via an external OpenAPI specification file (api.yaml). +This pattern demonstrates direct integration between REST API Gateway 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 @@ -10,7 +12,7 @@ This AWS SAM template deploys a REST API Gateway with VPC Link V2 integration to * Security Groups for ALB and ECS tasks * ECS Fargate cluster with service and task definitions * Private Application Load Balancer with listener and target group -* VPC Link V2 connecting API Gateway to the private ALB +* Amazon VPC Link V2 connecting API Gateway to the private ALB * REST API Gateway (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/ @@ -36,7 +38,7 @@ Important: this application uses various AWS services and there are costs associ ``` 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 + sam deploy --guided --capabilities CAPABILITY_NAMED_IAM ``` 4. During the prompts: * Enter a stack name @@ -55,7 +57,7 @@ Important: this application uses various AWS services and there are costs associ 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 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. +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 @@ -84,6 +86,6 @@ Expected response: **200** aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus" ``` ---- -Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +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/template.yaml b/apigw-rest-vpclink-pvt-alb-sam/template.yaml index c60e43494..e3b4ae8da 100644 --- a/apigw-rest-vpclink-pvt-alb-sam/template.yaml +++ b/apigw-rest-vpclink-pvt-alb-sam/template.yaml @@ -219,23 +219,3 @@ Outputs: RestApiEndpoint: Description: REST API Gateway Endpoint URL Value: !Sub 'https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/prod' - - RestApiId: - Description: REST API Gateway ID - Value: !Ref RestApi - - VpcLinkId: - Description: VPC Link V2 ID - Value: !Ref VpcLink - - ALBDnsName: - Description: Private ALB DNS name - Value: !GetAtt PrivateALB.DNSName - - ECSClusterName: - Description: ECS cluster name - Value: !Ref ECSCluster - - ECSServiceName: - Description: ECS service name - Value: !GetAtt ECSService.Name From 377b79ebaa6ff3f67d2951bc325fb01607f3c18f Mon Sep 17 00:00:00 2001 From: ellisms <114107920+ellisms@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:46:06 -0500 Subject: [PATCH 7/9] minor service name edits --- apigw-rest-vpclink-pvt-alb-sam/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apigw-rest-vpclink-pvt-alb-sam/README.md b/apigw-rest-vpclink-pvt-alb-sam/README.md index f58654f87..2062ba99a 100644 --- a/apigw-rest-vpclink-pvt-alb-sam/README.md +++ b/apigw-rest-vpclink-pvt-alb-sam/README.md @@ -1,8 +1,8 @@ -# REST Amazon API Gateway to Private HTTP Endpoint via Amazon VPC Link V2 +# Amazon API Gateway REST API to Private HTTP Endpoint via Amazon VPC Link V2 -This pattern demonstrates direct integration between REST API Gateway 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 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). +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 @@ -12,8 +12,8 @@ This AWS SAM template deploys a REST API Gateway with Amazon VPC Link V2 integra * 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 -* REST API Gateway (AWS::Serverless::Api) with proxy integration to the ALB +* 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/ From 460084ad55adc023b0fe5c7141a022c05b70d2ae Mon Sep 17 00:00:00 2001 From: ellisms <114107920+ellisms@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:46:53 -0500 Subject: [PATCH 8/9] tagging --- apigw-rest-vpclink-pvt-alb-sam/template.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apigw-rest-vpclink-pvt-alb-sam/template.yaml b/apigw-rest-vpclink-pvt-alb-sam/template.yaml index e3b4ae8da..e9f4608c7 100644 --- a/apigw-rest-vpclink-pvt-alb-sam/template.yaml +++ b/apigw-rest-vpclink-pvt-alb-sam/template.yaml @@ -1,6 +1,6 @@ AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 -Description: REST API Gateway to Private ALB and ECS Fargate via VPC Link V2 +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: From 5ecb0eea5d2eaf32e54d0af95876d4b0cabdf612 Mon Sep 17 00:00:00 2001 From: ellisms <114107920+ellisms@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:35:28 -0500 Subject: [PATCH 9/9] publishing file --- .../apigw-rest-vcplink-pvt-alb-sam.json | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 apigw-rest-vpclink-pvt-alb-sam/apigw-rest-vcplink-pvt-alb-sam.json 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" + } + } +}