n4nAI

Private networking and VPC peering for LLM API access

Practical steps to deploy a VPC peering LLM API gateway, with AWS CLI, routing, and private endpoint config to keep model traffic off the public internet.

n4n Team4 min read902 words

Audio narration

Coming soon — every post will get a voice note here.

Setting up a VPC peering LLM API gateway is the cleanest way to keep model inference traffic off the public internet while still accessing hundreds of third-party models. This guide walks through the concrete steps to peer your VPC with a gateway provider, lock down routing, and avoid the silent failures that bite teams later.

Map your trust boundaries

Before you open a peering connection, know exactly which subnets initiate LLM calls. A common mistake is peering the entire VPC and then wondering why a CI runner can now reach the gateway.

List the CIDR blocks for your application tier. Confirm there is no overlap with the gateway provider’s VPC CIDR. Overlapping CIDRs will cause the peering request to fail or, worse, silently blackhole routes.

Decide whether you need the gateway reachable from one subnet or many. Narrow scope reduces blast radius. If you run a hub-and-spoke topology, plan the peering from the hub only.

Request and accept the VPC peering connection

Assuming AWS, create the peering from your account to the gateway’s VPC. Replace the IDs with your real values.

aws ec2 create-vpc-peering-connection \
  --vpc-id vpc-0a1b2c3d \
  --peer-vpc-id vpc-4e5f6g7h \
  --peer-region us-east-1 \
  --tag-specifications 'ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=llm-gw-peer}]'

The gateway side must accept. If you manage both sides, run:

aws ec2 accept-vpc-peering-connection \
  --vpc-peering-connection-id pcx-0abc123

A VPC peering LLM API gateway connection is not transitive. If you later add a second VPC, you need a separate peering or a transit gateway.

Update route tables and security groups

Peering alone does nothing until you route traffic. Add a route in your app subnet’s route table pointing to the gateway CIDR.

aws ec2 create-route \
  --route-table-id rtb-0app123 \
  --destination-cidr-block 10.20.0.0/16 \
  --vpc-peering-connection-id pcx-0abc123

On the gateway side, ensure its route table sends return traffic to your VPC CIDR.

Security groups must explicitly allow TCP 443 from your app subnet. A common pitfall is leaving the default deny and staring at timeouts.

aws ec2 authorize-security-group-ingress \
  --group-id sg-0gw456 \
  --protocol tcp \
  --port 443 \
  --cidr 10.10.0.0/20

Terraform for repeatability

If you provision with code, encode the same in HCL:

resource "aws_vpc_peering_connection" "gw" {
  vpc_id        = aws_vpc.app.id
  peer_vpc_id   = "vpc-4e5f6g7h"
  peer_region   = "us-east-1"
  auto_accept   = false
  tags = { Name = "llm-gw-peer" }
}

resource "aws_route" "to_gw" {
  route_table_id            = aws_route_table.app.id
  destination_cidr_block    = "10.20.0.0/16"
  vpc_peering_connection_id = aws_vpc_peering_connection.gw.id
}

Configure the gateway’s private endpoint

Most gateways expose an OpenAI-compatible HTTPS endpoint. With peering established, swap the public hostname for the private one supplied by the provider.

from openai import OpenAI

client = OpenAI(
    base_url="https://llm.internal.peering.example.com/v1",
    api_key="sk-your-token",
)

resp = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "ping"}],
)
print(resp.choices[0].message.content)

A gateway like n4n.ai exposes one OpenAI-compatible endpoint covering 240+ models; point your private DNS at its peered interface and you inherit automatic fallback when a provider is rate-limited or degraded, without changing client code.

If the provider hands you a private DNS name, enable enableDnsResolution on the peering so names resolve across VPCs.

aws ec2 modify-vpc-peering-connection-options \
  --vpc-peering-connection-id pcx-0abc123 \
  --requester-peering-connection-options DnsResolutionSupport=enabled

When deploying a VPC peering LLM API gateway, you replace public DNS with private resolution. Verify with dig llm.internal.peering.example.com from an app instance; it must return a private IP.

Enforce egress control and IAM

Once the peering is live, block the public NAT path for the app subnet. Otherwise your client library may still use the public internet if DNS fails. Use a VPC endpoint for any AWS APIs (S3 for prompt caches, etc.) and a strict outbound rule.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "NotIpAddress": {"aws:SourceIp": "10.20.0.0/16"}
      }
    }
  ]
}

Attach an IAM policy that only permits ec2:CreateRoute from your Terraform pipeline, not from arbitrary instances. Least privilege prevents a compromised container from rewiring traffic.

Validate connectivity and latency

SSH into an instance in the app subnet and curl the health check.

curl -s https://llm.internal.peering.example.com/v1/models \
  -H "Authorization: Bearer sk-your-token" | head

Measure p99 latency from inside the VPC versus public internet. Peering usually cuts 1–3 ms but adds nothing magical; if your provider is in another region, cross-region peering latency dominates.

A VPC peering LLM API gateway path should be tested for failure modes: kill the route temporarily and confirm your app degrades gracefully, not silently retries forever.

Meter and observe

Per-token usage metering is non-negotiable for cost control. Capture the x-usage headers or the JSON usage field and ship to your metrics pipeline.

resp = client.chat.completions.create(
    model="claude-3-5-sonnet",
    messages=[{"role": "user", "content": "report tokens"}],
)
print(resp.usage.prompt_tokens, resp.usage.completion_tokens)

If the gateway honors client routing directives and forwards provider cache-control hints, log those to verify cache hits across peering.

Set CloudWatch alarms on peering byte counts. A sudden drop to zero means the route disappeared; a spike may indicate a misconfigured batch job.

VPC peering connects two VPCs at layer 3. AWS PrivateLink exposes a service via ENI in your VPC. For a VPC peering LLM API gateway, peering is simpler if the provider publishes their VPC ID. PrivateLink shifts the burden to the provider and avoids CIDR exposure but costs more per hour.

Tradeoff: peering reveals your CIDR to the provider; PrivateLink hides it. Pick peering for speed, PrivateLink for strict isolation.

Common pitfalls and tradeoffs

CIDR overlap. You cannot peer if both sides use 10.0.0.0/16. Re-number or use a transit gateway with NAT.

DNS leakage. Without enableDnsResolution, your private hostname may resolve to a public IP via public Route 53. Always verify with dig from the instance.

Non-transitive peering. A VPC peering LLM API gateway connection links two VPCs only. A third environment needs its own connection or a hub-and-spoke model.

Provider-side restrictions. Some model providers forbid private peering or require business-tier contracts. Read the fine print before committing architecture.

Data transfer costs. AWS charges for cross-VPC peering bytes. At high inference volume, that line item rivals the model cost itself.

Fallback behavior. Automatic fallback is great until it silently routes sensitive prompts to a provider you didn’t vet for compliance. Pin models explicitly when needed.

Final checklist

  • App subnet CIDR documented, no overlap
  • Peering requested, accepted, DNS resolution on
  • Route table and SG updated both sides
  • Private base_url configured in client
  • Public NAT blocked for egress
  • Usage metering and alarms live

Follow that order and the VPC peering LLM API gateway setup becomes a routine change, not a fire drill.

Tagsvpcprivate-networkingenterprisesecurity

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All best gateway for enterprise posts →