Deploying a Private API Gateway on AWS: How to Implement

Many APIs should never be exposed to the public internet. Internal microservices, data pipelines, and admin tools are better served by a private API layer that only your VPC (or connected networks) can reach. This guide walks through implementing a private REST API with Terraform. Reference repo: terraform-private-apigw.

Private API and VPC architecture
A private API Gateway endpoint is only resolvable within your VPC.

When to use a private API Gateway

Use a private API when your API consumers are entirely inside AWS (e.g. ECS tasks, Lambda, EC2) or connected via VPN/Direct Connect. The API Gateway endpoint is then only resolvable within your VPC (via DNS or a VPC endpoint), so it never appears on the public internet.

Steps to deploy

  1. Create the API: Create a REST API and add a resource policy that allows ExecuteApi only from your VPC (e.g. aws:SourceVpce or aws:SourceVpc). Attach the policy so the API becomes private.
  2. Create a VPC Link: Create a VPC Link (Network for NLB or Application for ALB) pointing at your NLB or ALB. Wait until status is "Available".
  3. Define resources and methods: Add resources and methods; set integration type to VPC Link and specify the backend URL.
  4. Deploy the API: Deploy to a stage (e.g. prod). Invoke URL: https://api-id.execute-api.region.amazonaws.com/prod. Only reachable from within the VPC.

Terraform: resource policy (private API)

Example resource policy so the API is only invokable from your VPC endpoint:

resource "aws_api_gateway_rest_api_policy" "private" {
  rest_api_id = aws_api_gateway_rest_api.main.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = "*"
      Action    = "execute-api:Invoke"
      Resource  = "${aws_api_gateway_rest_api.main.execution_arn}/*"
      Condition = {
        StringEquals = {
          "aws:SourceVpce" = aws_vpc_endpoint.api_gateway.id
        }
      }
    }]
  })
}

Create an interface VPC endpoint for com.amazonaws.region.execute-api and reference it in the condition. Full Terraform: terraform-private-apigw.

Accessing the private API

Create an interface VPC endpoint for API Gateway (com.amazonaws.region.execute-api) in your VPC. Clients in the VPC then resolve the API invoke URL to the VPC endpoint. Ensure the endpoint security group allows outbound HTTPS (443) and the resource policy allows the endpoint (or VPC) as source.

Security and best practices

  • Keep the resource policy strict: allow only the VPC or VPC endpoints you intend.
  • Use IAM authorization or Lambda authorizers so only authorized roles can call the API.
  • Enable access logging and CloudWatch metrics for audit and monitoring.

Summary

Create a private REST API with a VPC-restricted resource policy, connect it to your backend via VPC Link, deploy to a stage, and expose it via an interface VPC endpoint. Combine with IAM or custom authorizers and logging for a production-ready private API.