AWS VPC Lattice quietly became one of the more useful networking services in the AWS catalog, and 2026 gave it three upgrades that finally make it worth a proper setup guide: dual-stack IPv6 support for management endpoints, configurable IP addresses for resource gateways, and a Kubernetes Gateway API controller that AWS says now delivers complete east-west and north-south coverage for EKS clusters. If you have spent hours untangling VPC peering, Transit Gateway route tables, or PrivateLink endpoint services just to let two microservices talk to each other across accounts, this tutorial walks through building that connection with VPC Lattice instead, from the first IAM permission to a working multi-account service network you can test with curl.
By the end you will have a service network with associated VPCs, a target group registered against real compute (EC2, ECS, or Lambda), a listener with an IAM-based zero-trust auth policy, a custom domain backed by TLS, and an EKS workload wired up through the Gateway API controller. Every command below reflects the current AWS CLI, Terraform AWS provider, and VPC Lattice API as of September 2026.
Don't miss new tech stories on Google
Add Tech Insider once in the Google app and our stories appear in your news suggestions.
What Is AWS VPC Lattice, and Why It Matters in September 2026
Amazon VPC Lattice is a fully managed application-layer networking service that connects, secures, and monitors services across VPCs, AWS accounts, and compute types without you having to manage peering connections, load balancers, or sidecar proxies for every workload. It reached general availability on March 31, 2023, after a preview limited to US West (Oregon), and since then AWS has treated it as the default answer to a recurring problem: how do you let an ECS task in one account call a Lambda function in another account, with per-request IAM authorization, without hand-building a mesh of VPC peering and security group rules.
Three things changed in the last 18 months that make VPC Lattice worth revisiting even if you looked at it in 2023 and decided it was too new. First, AWS added dual-stack IPv4/IPv6 support for VPC Lattice management endpoints on April 30, 2025, which matters if your organization is on an IPv6 migration timeline. Second, on October 7, 2025, AWS shipped configurable IP addresses for resource gateways, giving teams more control over how VPC Lattice reaches TCP resources like databases running outside a standard target group. Third, and most significant for platform teams, an AWS containers blog update dated March 31, 2026 confirmed that Gateway API coverage for EKS is now complete: the VPC Lattice Gateway API controller handles east-west (service-to-service) traffic, while the AWS Load Balancer Controller handles north-south (ingress) traffic, both through the same Kubernetes Gateway API resources.
AWS also extended VPC Lattice to Oracle Database@AWS on June 26, 2025, and added built-in support for Amazon ECS and AWS Fargate as native targets alongside the original EC2, EKS, and Lambda support. Put together, VPC Lattice in 2026 covers a wider slice of the compute and database landscape than it did at launch, which is why it now shows up as the default recommendation in a lot of AWS reference architectures for multi-account microservices. AWS’s own product page describes it as a way to connect, secure, and monitor services across instances, containers, and serverless applications, and the official VPC Lattice overview is worth bookmarking alongside this tutorial for release notes.
The Service Network Model: Terminology You’ll See Everywhere
Before touching the CLI, it helps to know the four nouns VPC Lattice uses for everything, because the console, the API, and Terraform all reuse them consistently. A service network is the top-level container, the boundary that groups everything else together. A service is a single addressable application endpoint, the thing another team calls. A target group defines the compute behind a service (EC2, IP, Lambda, or ALB type). And a resource configuration, paired with a resource gateway, represents a non-HTTP TCP endpoint like a database that gets exposed through the same access model.
The distinction that trips people up most is between associating a VPC with a service network versus associating a service with a service network. The first grants an entire VPC the ability to reach anything on that network, subject to auth policies. The second publishes a specific service onto the network so other associated VPCs can find it. You need both directions configured, or requests fail silently with no obvious error pointing at the missing half. AWS’s VPC Lattice user guide keeps this terminology current as the service evolves, so it is worth cross-referencing if a command in this tutorial ever drifts from the latest API shape.
Prerequisites: Tools, Versions, and Permissions You Need
Before you start, confirm you have the following in place. None of this is exotic, but VPC Lattice touches IAM, VPC networking, and compute simultaneously, so it is easy to miss one piece.
- An AWS account with administrator access or an IAM role with
vpc-lattice:*,ec2:*VpcEndpoint*,ram:*, and target-service permissions (ECS, Lambda, or EC2, depending on what you register) - AWS CLI v2.19 or later (VPC Lattice commands were added incrementally, so an older v2 build may be missing subcommands like
put-auth-policy) - At least one VPC with a minimum of two subnets in different Availability Zones, since VPC Lattice associates at the VPC level, not the subnet level
- Terraform 1.7 or later if you plan to use the infrastructure-as-code example later in this guide, with the
hashicorp/awsprovider at version 5.40 or newer - Existing compute to register as a target: an EC2 instance, an ECS service on Fargate, an EKS cluster running Kubernetes 1.28 or later, or a Lambda function
- kubectl and Helm 3 if you plan to install the Gateway API controller for EKS (Step 12 below)
- A registered domain name and an ACM certificate if you want a custom hostname instead of the auto-generated VPC Lattice FQDN
Budget about 90 minutes for the core setup (service network through a working test call) and another 45 minutes if you are also wiring up the Kubernetes Gateway API controller.
VPC Lattice vs Transit Gateway vs PrivateLink vs App Mesh
The most common question when evaluating VPC Lattice is where it fits next to services you may already use. The short version: Transit Gateway and PrivateLink solve network-layer (L3/L4) connectivity, while VPC Lattice and App Mesh solve application-layer (L7) connectivity, and VPC Lattice is generally what AWS now points customers to instead of App Mesh for new projects.
| Service | Layer | Setup model | Best fit |
|---|---|---|---|
| VPC Lattice | L7 (HTTP, HTTPS, gRPC, TLS, TCP) | Managed, no sidecars, no route tables | Service-to-service auth, routing, and observability across VPCs and accounts |
| Transit Gateway | L3 routing | Hub-and-spoke, manual route tables | Bulk IP-level connectivity between many VPCs and on-prem networks |
| AWS PrivateLink | L3/L4 endpoint | Per-service endpoint, mostly point-to-point | Privately consuming a single specific service across accounts |
| App Mesh | L7 service mesh | Requires Envoy sidecars on every task | Legacy Envoy-based meshes, though AWS now steers new workloads toward VPC Lattice instead |
If you already run an Application Load Balancer or Network Load Balancer in front of each service, VPC Lattice does not replace that ingress layer. It replaces the east-west connections between services, which is exactly the gap that made teams reach for Istio, Linkerd, or Cilium in the first place. If you are still deciding between a full service mesh like Istio, Linkerd, or Cilium and a managed AWS-native option, VPC Lattice is worth testing first for pure AWS-to-AWS traffic, since it removes the sidecar tax entirely.
Step 1-3: Set Up IAM Permissions and Create Your Service Network
Step 1: Attach the IAM permissions. Create or update an IAM policy that grants your deployment role access to the VPC Lattice API. At minimum you need vpc-lattice:CreateServiceNetwork, vpc-lattice:CreateService, vpc-lattice:CreateTargetGroup, vpc-lattice:RegisterTargets, vpc-lattice:CreateListener, vpc-lattice:PutAuthPolicy, and vpc-lattice:CreateServiceNetworkVpcAssociation. Use the AWS managed policy VPCLatticeFullAccess for initial testing, then scope it down to only the actions above for production.
Step 2: Create the service network. The service network is the top-level container that groups your services and the VPCs allowed to reach them. Run this with the AWS CLI:
aws vpc-lattice create-service-network \
--name "prod-microservices-network" \
--auth-type "AWS_IAM" \
--tags Key=Environment,Value=production
# Response includes an ARN and ID you'll reuse in later steps, e.g.
# "id": "sn-0a1b2c3d4e5f6g7h8"
Step 3: Associate your VPCs. Every VPC that needs to reach services on this network has to be associated explicitly. Repeat this for each VPC, including ones in different accounts if you are building a cross-account setup (covered under Resource Access Manager in the advanced tips section further down).
aws vpc-lattice create-service-network-vpc-association \
--service-network-identifier sn-0a1b2c3d4e5f6g7h8 \
--vpc-identifier vpc-0123456789abcdef0 \
--security-group-ids sg-0987654321fedcba0
By default, VPC Lattice allows a quota of 50 service networks per Region per account, and each service network can have up to 500 VPC associations, so a single network comfortably covers a large multi-team platform without hitting limits on day one.
Step 4-6: Register Compute Targets Across EC2, ECS, EKS, and Lambda
Step 4: Create a target group. A target group tells VPC Lattice what kind of compute it is routing to. VPC Lattice supports four target group types: instance (EC2), IP, Lambda, and ALB. For a Fargate-backed ECS service, you typically use the IP type, since ECS tasks get elastic network interfaces with private IPs rather than a persistent instance ID.
aws vpc-lattice create-target-group \
--name "checkout-service-tg" \
--type IP \
--config '{
"vpcIdentifier": "vpc-0123456789abcdef0",
"port": 8080,
"protocol": "HTTPS",
"ipAddressType": "IPV4",
"healthCheck": {
"enabled": true,
"protocol": "HTTPS",
"path": "/healthz",
"healthCheckIntervalSeconds": 30,
"healthyThresholdCount": 3,
"unhealthyThresholdCount": 3
}
}'
Step 5: Register your targets. Once the target group exists, register the actual IPs, instance IDs, or Lambda ARN. For a Lambda-backed target group, skip the health check block entirely, since Lambda manages its own availability.
aws vpc-lattice register-targets \
--target-group-identifier tg-0a1b2c3d4e5f6g7h8 \
--targets Id=10.0.1.15,Port=8080 Id=10.0.2.22,Port=8080
Step 6: Repeat for each compute type you use. A single service network can hold target groups pointing at EC2, ECS, EKS, and Lambda simultaneously. That is the core value here: a checkout service running on ECS can talk to a fraud-scoring Lambda function and a legacy pricing engine on EC2, all through the same auth model and observability pipeline, with no code changes in any of the three services. AWS built VPC Lattice specifically so that adopting it requires only infrastructure configuration, not application code changes.
Step 7-9: Create the Service, Add a Listener, and Write a Zero-Trust Auth Policy
Step 7: Create the VPC Lattice service. The service is the addressable object other workloads will call. VPC Lattice auto-generates a DNS name for it unless you attach a custom domain later.
aws vpc-lattice create-service \
--name "checkout-service" \
--auth-type "AWS_IAM"
Step 8: Add a listener and a forwarding rule. The listener defines the protocol and port VPC Lattice accepts traffic on, then routes it to your target group. HTTPS listeners terminate TLS 1.2 at VPC Lattice by default and support both HTTP/1.1 and HTTP/2, or you can choose TLS passthrough, added May 14, 2024, if your application needs to terminate TLS itself for end-to-end encryption.
aws vpc-lattice create-listener \
--service-identifier svc-0a1b2c3d4e5f6g7h8 \
--name "https-listener" \
--protocol HTTPS \
--port 443 \
--default-action '{
"forward": {
"targetGroups": [{"targetGroupIdentifier": "tg-0a1b2c3d4e5f6g7h8", "weight": 100}]
}
}'
Step 9: Write and attach the IAM auth policy. This is where VPC Lattice earns its zero-trust description. Instead of relying purely on security groups, every request can be evaluated against an IAM-style JSON policy at the service network or service level, checked at request time.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/fraud-scoring-lambda-role"
},
"Action": "vpc-lattice-svcs:Invoke",
"Resource": "arn:aws:vpc-lattice:us-east-1:111122223333:service/svc-0a1b2c3d4e5f6g7h8/*",
"Condition": {
"StringEquals": {
"vpc-lattice-svcs:RequestMethod": "POST"
}
}
}
]
}
aws vpc-lattice put-auth-policy \
--resource-identifier svc-0a1b2c3d4e5f6g7h8 \
--policy file://checkout-service-auth-policy.json
Auth policies are capped at 10 KB per Region, and that limit is not adjustable, so keep policies scoped to specific roles and actions rather than trying to encode your entire org chart into one document. This request-level authorization is what separates VPC Lattice from a plain PrivateLink endpoint, where authorization mostly stops at whether a given VPC is allowed to reach the endpoint at all.
Step 10-11: Add a Custom Domain and Test Connectivity End to End
Step 10: Attach a custom domain. The auto-generated FQDN works fine for internal testing, but production services usually want a readable hostname. Request or import a certificate in ACM first, then associate it with the service.
aws vpc-lattice update-service \
--service-identifier svc-0a1b2c3d4e5f6g7h8 \
--custom-domain-name "checkout.internal.example.com" \
--certificate-arn "arn:aws:acm:us-east-1:111122223333:certificate/abcd1234-ef56-7890-abcd-1234567890ab"
You get up to 5 domain verifications per Region by default, adjustable through a service quota increase request if you run many customer-facing services on VPC Lattice.
Step 11: Test the connection. From an EC2 instance, ECS task, or Cloud9 environment inside an associated VPC, call the service using its generated FQDN or your custom domain.
curl -v https://checkout-service-abc123.7d67968.vpc-lattice-svcs.us-east-1.on.aws/healthz
# Expect: HTTP/2 200
# A 403 here usually means the auth policy is the problem, not the network
If the call succeeds from inside an associated VPC but fails from an unassociated one, that is expected behavior, not a bug. VPC Lattice only routes traffic from VPCs explicitly associated with the service network, which is the entire point of the access model.
Step 12-13: Turn On Observability and Connect EKS With the Gateway API Controller
Step 12: Enable access logs. VPC Lattice can stream access logs to CloudWatch Logs, S3, or Kinesis Data Firehose. For most teams, CloudWatch Logs is the fastest way to start debugging routing and auth issues.
aws vpc-lattice create-access-log-subscription \
--resource-identifier svc-0a1b2c3d4e5f6g7h8 \
--destination-arn "arn:aws:logs:us-east-1:111122223333:log-group:/vpc-lattice/checkout-service"
Step 13: Install the Gateway API controller for EKS. If you run workloads on Kubernetes, the AWS Gateway API controller for VPC Lattice lets you manage service networking through native Kubernetes Gateway API resources like Gateway and HTTPRoute, instead of the raw VPC Lattice API. The latest standalone controller release was v1.1.3 on July 11, 2025, and the broader Gateway API controller stack documented in AWS’s user guide was at chart version v2.1.3 as of August 2026. Install it with Helm, then deploy a Gateway using the amazon-vpc-lattice GatewayClass.
helm install gateway-api-controller \
oci://public.ecr.aws/aws-application-networking-k8s/aws-gateway-controller-chart \
--version 1.1.3 \
--namespace aws-application-networking-system \
--create-namespace \
--set=serviceAccount.create=true \
--set=clusterName=prod-eks-cluster
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: internal-gateway
spec:
gatewayClassName: amazon-vpc-lattice
listeners:
- name: https
protocol: HTTPS
port: 443
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: checkout-route
spec:
parentRefs:
- name: internal-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /checkout
backendRefs:
- name: checkout-service
kind: Service
port: 8080
Once applied, the controller registers your Kubernetes Service as a VPC Lattice target group automatically, so pods in one EKS cluster can reach services in a completely different cluster, VPC, or account through the same service network built in Step 2. If you currently route internal traffic through a traditional ingress controller, this is worth comparing against your existing Kubernetes Ingress setup, since VPC Lattice’s Gateway API path removes the need for a separate east-west proxy layer entirely.
Step 14: Expose Databases and On-Premises Systems With VPC Resources
VPC Resources, expanded with configurable resource gateway IP addresses on October 7, 2025, let you put non-HTTP TCP endpoints, such as a PostgreSQL database, an on-premises system reachable over a VPN, or an Oracle Database@AWS instance, behind the same VPC Lattice access model built for HTTP services above. This closes a gap that used to force teams back to PrivateLink or Transit Gateway just to reach a database securely across accounts.
aws vpc-lattice create-resource-gateway \
--name "prod-db-gateway" \
--vpc-identifier vpc-0123456789abcdef0 \
--subnet-ids subnet-0a1b2c3d subnet-0e5f6g7h \
--ip-address-type IPV4
aws vpc-lattice create-resource-configuration \
--name "billing-postgres" \
--resource-gateway-identifier rgw-0a1b2c3d4e5f6g7h \
--type SINGLE \
--resource-configuration-definition '{
"ipResource": {"ipAddress": "10.0.3.45"}
}' \
--port-ranges 5432
VPC Resources bill separately from standard VPC Lattice services, using a tiered per-GB rate that drops as volume grows, which the pricing section below breaks down in full.
AWS VPC Lattice Pricing in 2026: What You’ll Actually Pay
VPC Lattice pricing has three core dimensions: an hourly charge per service, a per-GB charge for data processed, and a per-request charge above a free tier. Rates vary by Region, with US East (N. Virginia) as the baseline and higher rates in Regions like Tokyo.
| Pricing dimension | US East (N. Virginia) | Asia Pacific (Tokyo) |
|---|---|---|
| Per service, per hour | $0.025 | $0.0325 |
| Data processed, per GB | $0.025 | $0.0325 |
| Requests, per million | $0.10 (first 300,000 requests/hour free) | Varies by Region |
| VPC Resources, per GB (first PB/Region/month) | $0.01 | Varies by Region |
| VPC Resources, per GB (next tier) | $0.006 | Varies by Region |
| VPC Resources, per GB (highest tier) | $0.004 | Varies by Region |
For a rough monthly estimate, a service network with five services running continuously costs about $90 a month just in service-hours (5 services times $0.025 times 730 hours), before any data processing or request charges. That is roughly comparable to running a small internal Network Load Balancer per service, but you gain IAM-based request auth, cross-account service discovery, and unified observability that a plain NLB does not give you. Check the official AWS VPC Lattice pricing page for your specific Region before committing to production traffic, since rates are set per Region and do change over time.
Security Model: What VPC Lattice Protects Against, and What It Doesn’t
VPC Lattice’s auth policies handle authorization: they decide which identity is allowed to call which service, and under what conditions. They do not replace network-level controls like security groups, and they do not inspect request bodies for malicious payloads the way a web application firewall does. Treat VPC Lattice as one layer in a defense-in-depth setup, not a full replacement for existing security tooling.
In practice, that means keeping security groups on your targets tightened to only the VPC Lattice managed prefix list, even though the auth policy already restricts who can call the service. If an auth policy is misconfigured to be too permissive, a locked-down security group is what stops a compromised workload in an associated VPC from reaching resources it should not. Pair VPC Lattice with the documented auth policy structure and standard IAM least-privilege practices, and audit both together whenever you onboard a new team to a shared service network.
Access logs, covered in Step 12, double as your audit trail here. Every entry records the calling identity, the resource requested, and the auth decision, which makes VPC Lattice access logs a reasonable source of truth during a security review, separate from whatever application-level logging your services already produce.
Monitoring VPC Lattice With CloudWatch Metrics
Beyond access logs, VPC Lattice publishes request count, response time, and error rate metrics to CloudWatch automatically, broken out by target group and by HTTP status code family (2xx, 4xx, 5xx). Set an alarm on the 5xx rate per target group before you go to production, since that is usually the fastest signal that a newly registered target is failing health checks or throwing errors under real traffic rather than synthetic test calls.
aws cloudwatch put-metric-alarm \
--alarm-name "checkout-tg-high-5xx-rate" \
--namespace "AWS/VpcLattice" \
--metric-name "HTTPCode_Target_5XX_Count" \
--dimensions Name=TargetGroup,Value=tg-0a1b2c3d4e5f6g7h8 \
--statistic Sum \
--period 60 \
--threshold 10 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:111122223333:platform-alerts
Combine this with the access log subscription from Step 12, and you get both the aggregate trend (CloudWatch) and the per-request detail (logs) needed to debug an incident without switching tools mid-investigation.
Service Quotas and Limits to Plan Around
Most VPC Lattice quotas are generous enough that small and mid-size platforms will not hit them, but a few are worth knowing before you design a large multi-team rollout.
| Quota | Default | Adjustable |
|---|---|---|
| Service networks per Region per account | 50 | Yes |
| Resource configurations per service network | 500 | Yes |
| Resource configurations per Region per account | 2,000 | Yes |
| VPC associations per service network | 500 | Yes |
| Listeners per service | 2 | Yes |
| Auth policy size | 10 KB per Region | No |
| Domain verifications per Region | 5 | Yes |
| Bandwidth per service per Availability Zone | 10 Gbps | Yes, via support request |
| Requests per second per service per AZ (HTTP) | 10,000 | Yes, via support request |
The two limits that catch teams off guard most often are the 10 KB auth policy cap and the default 2 listeners per service. If you find yourself trying to cram dozens of path-based rules into a single auth policy or listener, that is usually a sign you need more services, not a bigger policy document. Check the full quotas table in AWS’s own VPC Lattice service quotas documentation before finalizing a production architecture.
5 Common Pitfalls When Deploying VPC Lattice
- Forgetting the VPC association. Creating a service and target group without associating the calling VPC to the service network is the single most common cause of “it worked in my test VPC but not from the app team’s VPC.”
- Mixing up service-level and service-network-level auth policies. A permissive service network policy combined with a restrictive service policy, or the reverse, produces confusing 403 errors. Both are evaluated, and the more restrictive one wins.
- Choosing the wrong target group type for ECS. Teams often default to the instance target group type out of habit, when Fargate tasks almost always need the IP target group type, since they do not have a persistent EC2 instance ID.
- Setting IP address type on a target group and expecting to change it later. Once you pick IPv4 or IPv6 for an IP-type target group, you cannot switch it. Decide your addressing strategy before registering targets, not after.
- Skipping health checks on non-Lambda target groups. Health checks are optional but effectively mandatory for anything other than Lambda. Without them, VPC Lattice keeps routing to unhealthy targets and requests silently fail.
Troubleshooting: 8 VPC Lattice Errors and How to Fix Them
- 403 Forbidden on every request. Check the auth policy attached to both the service and the service network. A missing or overly narrow Principal block is the usual cause, not a networking issue.
- Connection timeout, no response at all. Confirm the calling VPC is actually associated with the service network (Step 3), and that security groups on the target allow inbound traffic from the VPC Lattice managed prefix list.
- Targets show as unhealthy in the console. Verify the health check path returns a 200 on the exact port and protocol configured, and that the target’s security group allows the health check traffic.
- HTTPS listener fails TLS handshake. Confirm the ACM certificate used is in the same Region as the service and covers the custom domain name exactly, including any wildcard requirements.
- Lambda target returns 500 errors. Check that the Lambda function’s resource-based policy grants vpc-lattice.amazonaws.com permission to invoke it. VPC Lattice needs its own invoke permission, separate from IAM auth policies.
- Cross-account service not visible. Confirm you shared the service network through AWS Resource Access Manager and that the receiving account accepted the resource share invitation.
- Gateway API controller not creating target groups. Check controller pod logs in the aws-application-networking-system namespace, and confirm the IAM role attached to the controller’s service account has VPC Lattice write permissions through IRSA.
- Custom domain resolves but returns a certificate mismatch. DNS for a custom domain is your responsibility. Create a CNAME or ALIAS record pointing to the VPC Lattice-generated FQDN, since VPC Lattice does not manage Route 53 records for you automatically.
Advanced Tips: Cross-Account Sharing, Weighted Routing, and Terraform
For cross-account setups, share the service network through AWS Resource Access Manager rather than trying to recreate resources in every account. In the owning account, create a resource share targeting the service network ARN, then accept it in each consuming account before running the VPC association command from Step 3.
Weighted target groups are useful for canary or blue-green deployments. Instead of a single target group at 100 percent weight, split traffic across two target groups, old and new versions, and shift the weight gradually.
resource "aws_vpclattice_listener_rule" "canary" {
listener_identifier = aws_vpclattice_listener.https.listener_id
service_identifier = aws_vpclattice_service.checkout.id
priority = 10
match {
http_match {
path_match {
match {
exact = "/checkout"
}
}
}
}
action {
forward {
target_groups {
target_group_identifier = aws_vpclattice_target_group.checkout_v1.id
weight = 90
}
target_groups {
target_group_identifier = aws_vpclattice_target_group.checkout_v2.id
weight = 10
}
}
}
}
For teams standardizing on Terraform, the hashicorp/aws provider covers the full VPC Lattice resource model, including aws_vpclattice_service_network, aws_vpclattice_service, aws_vpclattice_target_group, and aws_vpclattice_auth_policy, so you rarely need to fall back to raw CLI calls or CloudFormation custom resources once you move past initial testing.
If you are migrating off App Mesh rather than starting fresh, do it service by service instead of in one cutover. Keep the existing Envoy sidecars running while you register the same ECS tasks or EKS pods as VPC Lattice targets, point a small percentage of internal traffic at the new service using a weighted listener rule like the one above, and watch the CloudWatch error-rate metrics before shifting more weight. Once a service sits at 100 percent on VPC Lattice with no error spike over a full business cycle, remove its Envoy sidecar and App Mesh virtual node. This avoids the common mistake of retiring App Mesh mesh-wide before every dependent service has actually been validated on the new path.
Complete Working Project: A Multi-Account Microservices Network
Here is a condensed but complete Terraform module that builds the pattern this tutorial walked through: a service network, a VPC association, a target group pointing at an ECS Fargate service, an HTTPS listener, and an IAM auth policy scoped to a single consuming role. Save this as main.tf, run terraform init, then terraform apply.
provider "aws" {
region = "us-east-1"
}
resource "aws_vpclattice_service_network" "main" {
name = "prod-microservices-network"
auth_type = "AWS_IAM"
}
resource "aws_vpclattice_service_network_vpc_association" "app_vpc" {
vpc_identifier = var.app_vpc_id
service_network_identifier = aws_vpclattice_service_network.main.id
security_group_ids = [var.app_security_group_id]
}
resource "aws_vpclattice_target_group" "checkout" {
name = "checkout-service-tg"
type = "IP"
config {
port = 8080
protocol = "HTTPS"
vpc_identifier = var.app_vpc_id
health_check {
enabled = true
protocol = "HTTPS"
path = "/healthz"
healthy_threshold = 3
unhealthy_threshold = 3
interval = 30
}
}
}
resource "aws_vpclattice_service" "checkout" {
name = "checkout-service"
auth_type = "AWS_IAM"
}
resource "aws_vpclattice_service_network_service_association" "checkout" {
service_identifier = aws_vpclattice_service.checkout.id
service_network_identifier = aws_vpclattice_service_network.main.id
}
resource "aws_vpclattice_listener" "https" {
name = "https-listener"
protocol = "HTTPS"
port = 443
service_identifier = aws_vpclattice_service.checkout.id
default_action {
forward {
target_groups {
target_group_identifier = aws_vpclattice_target_group.checkout.id
weight = 100
}
}
}
}
resource "aws_vpclattice_auth_policy" "checkout" {
resource_identifier = aws_vpclattice_service.checkout.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { AWS = var.consumer_role_arn }
Action = "vpc-lattice-svcs:Invoke"
Resource = "${aws_vpclattice_service.checkout.arn}/*"
}]
})
}
This module deploys in roughly two minutes and gives you a real, testable service network you can extend with more target groups, a custom domain, and the Kubernetes Gateway API controller as your platform grows. From here, the natural next step for many teams is layering in workload identity federation if part of the stack also spans Google Cloud, since VPC Lattice’s IAM-based auth model pairs naturally with a broader zero-trust identity strategy across clouds. Teams already running serverless workloads may also want to line this setup up against how they currently handle isolated Lambda execution environments, since VPC Lattice and Lambda’s own networking model interact directly once functions become targets.
Frequently Asked Questions
Is AWS VPC Lattice free to use?
No, but it is inexpensive at small scale. You pay $0.025 per service per hour, $0.025 per GB of data processed, and $0.10 per million requests above a free tier of 300,000 requests per hour in US East (N. Virginia), with rates varying slightly by Region.
What is the difference between VPC Lattice and AWS PrivateLink?
PrivateLink creates a point-to-point private connection to a single specific service. VPC Lattice manages an entire service network with shared routing, IAM-based request auth, and observability across many services and accounts at once, which makes it a better fit once you are connecting more than a couple of services.
Does VPC Lattice work with Kubernetes and EKS?
Yes, through the AWS Gateway API controller for VPC Lattice, an open-source Kubernetes controller in the aws/aws-application-networking-k8s repository. As of March 2026, AWS describes Gateway API coverage for EKS as complete, with VPC Lattice handling east-west traffic and the AWS Load Balancer Controller handling north-south ingress through the same Gateway API resources.
Can I use VPC Lattice across multiple AWS accounts?
Yes. Share the service network through AWS Resource Access Manager, then associate the consuming account’s VPCs with that shared service network before registering targets and testing connectivity.
What compute types can VPC Lattice target?
EC2 instances, ECS tasks including Fargate, EKS pods through the Gateway API controller, and Lambda functions. VPC Resources, expanded in October 2025, also let you reach TCP endpoints like databases and on-premises systems.
Does VPC Lattice support IPv6?
Yes. Management endpoints gained dual-stack IPv4/IPv6 support on April 30, 2025, and IP-type target groups let you choose IPv4 or IPv6 addressing at creation time, though that choice cannot be changed after the target group is created.
Is VPC Lattice a replacement for a full service mesh like Istio?
For AWS-to-AWS traffic, VPC Lattice covers most of what teams historically used App Mesh or a lightweight Istio deployment for: routing, request-level auth, and observability, without sidecar proxies. If you need mesh features across non-AWS infrastructure or highly custom traffic policies, a dedicated mesh like Istio, Linkerd, or Cilium still has a broader feature set.
Which AWS Region should I deploy VPC Lattice in first?
Start in whichever Region already hosts the majority of your compute, since VPC Lattice pricing and quotas are set per Region and cross-Region service networks are not supported. Most teams testing this for the first time use US East (N. Virginia), since it has the lowest published rates and the broadest feature availability.
How does VPC Lattice pricing compare to running my own service mesh?
Running Envoy sidecars yourself has no direct per-hour AWS charge, but it costs extra CPU and memory on every task, plus the engineering time to build and patch the control plane. VPC Lattice trades that operational overhead for a predictable per-service, per-GB, and per-request bill, which for most teams below a few hundred services ends up cheaper once headcount and sidecar resource overhead are factored in.
Can I use VPC Lattice with resources outside AWS, like an on-premises data center?
Yes, through VPC Resources and a resource gateway, as covered in Step 14. Point the resource gateway at a subnet with connectivity to your on-premises network over a VPN or Direct Connect, then register the on-prem system’s IP address as a resource configuration so it becomes reachable through the same access model as your AWS-native services.





