Portuguese version: Como conectar várias VPCs com o AWS Transit Gateway
Two applications on AWS. Each one lives in its own network. One day a development server needs to reach a directory that lives in another VPC, the shared-services network. The question sounds simple: how do you join those networks?
AWS gives you more than one answer. VPC Peering handles two networks cleanly. When you add a staging VPC, a production VPC, and a shared-services VPC, the same pattern turns into a mesh. AWS Transit Gateway shows up at that point: a hub in the middle, instead of a cable between every pair.
This is not a console click-through. It is the topology: what each piece does, where the packet goes, and when Peering is still the right tool.
The rest of this article uses a few terms over and over. Here they are.
A VPC (Virtual Private Cloud) is the virtual network for your account in one Region. A Region is a geographic cluster of data centers, for example us-east-1 (N. Virginia). Instances, load balancers, and databases live inside the VPC. One VPC does not talk to another VPC by default. They are isolated by default.
AWS splits each Region into Availability Zones: separate data centers in the same Region. If one zone fails, another can keep running. The letter at the end of the name (us-east-1a, us-east-1b) is the zone.
CIDR is how you write that network's IP range. In 10.0.0.0/16, the first 16 bits identify the network. The remaining 16 bits identify hosts: 65,536 addresses, from 10.0.0.0 to 10.0.255.255. The 10. prefix is private. It is not a public internet address. Two VPCs that must communicate cannot share the same block. If the ranges overlap, Peering refuses the connection. Transit Gateway may still accept the attachment, but it does not propagate the overlapping CIDR and does not route between identical or overlapping CIDRs. In both cases those two networks never talk.
A subnet is a slice of the VPC in one Availability Zone. An EC2 instance does not "live in the VPC" in the abstract. It gets an elastic network interface (ENI), a virtual network adapter, and that interface sits in a subnet.
The VPC route table is the list a subnet consults for the next hop. Destination 10.0.0.0/16 with target local means: this address is in this VPC, deliver it here. Any other destination needs another row. Without that row, the packet does not leave.
These are the four VPCs used throughout. The CIDRs below are the lab CIDRs. When an official AWS diagram shows VPC A and 10.1.0.0/16, ignore the numbers in the drawing and use this table:
| VPC | CIDR | Role |
|---|---|---|
VPC-DEV | 10.0.0.0/16 | development |
VPC-HML | 10.1.0.0/16 | staging |
VPC-PROD | 10.2.0.0/16 | production |
VPC-SHARED | 10.3.0.0/16 | shared services (a repository or a directory, for example) |
1. Two VPCs: VPC Peering is enough
Start with VPC-DEV (10.0.0.0/16) and VPC-SHARED (10.3.0.0/16). A service in DEV needs the directory in SHARED. Both networks are in the same Region. The CIDRs do not overlap.
VPC Peering is a network connection between exactly two VPCs. Traffic uses private IP addresses. It does not traverse the public internet. AWS builds it on the existing VPC infrastructure: it is not a VPN, it is not extra hardware in the path, and the documentation treats the connection as having no single point of failure and no bandwidth bottleneck of its own.
Source: VPC peering configurations with routes to an entire VPC, Amazon VPC. In the diagram, VPC A and VPC B. Read A as VPC-DEV and B as VPC-SHARED. Lab CIDRs are the ones in the table above, not whatever the official drawing happens to show.
Peering by itself does not move any packets. Each VPC needs a route that sends the other VPC's CIDR to the peering connection (the identifier starts with pcx-).
VPC-DEV route table:
| Destination | Target | Meaning |
|---|---|---|
10.0.0.0/16 | local | traffic for this VPC stays here |
10.3.0.0/16 | pcx-… (peering to SHARED) | anything for SHARED leaves through Peering |
VPC-SHARED route table:
| Destination | Target | Meaning |
|---|---|---|
10.3.0.0/16 | local | traffic for this VPC stays here |
10.0.0.0/16 | pcx-… (peering to DEV) | anything for DEV leaves through Peering |
Path of a packet from server 10.0.10.20 in DEV to directory 10.3.10.5 in SHARED:
- The DEV subnet consults the VPC route table.
-
10.3.10.5matches10.3.0.0/16. The target is the peering connection. - AWS delivers the packet into
VPC-SHAREDon the private path. - In SHARED,
10.3.10.5is local. The directory interface receives it. - The reply comes back through the same peering connection, because the SHARED table has the reverse route.
For two VPCs, that is enough. There is no hub in the middle. There is no extra route table beyond the VPC tables. Control is pairwise: if a route is missing, the networks do not talk.
2. More VPCs: the Peering mesh
Add VPC-HML (10.1.0.0/16) and VPC-PROD (10.2.0.0/16). Now all four networks need to talk. The DEV-SHARED peering from section 1 is still there. You still need the other connections.
This is the rule that changes the design. VPC Peering is not transitive. If DEV is peered with SHARED and DEV is peered with PROD, SHARED and PROD do not talk through DEV. AWS does not let a VPC act as a bridge.
Source: One VPC peered with two VPCs, Amazon VPC. VPC B and VPC C do not exchange traffic through VPC A.
In the diagram the center looks like a hub. It is not. Each line is a separate peering connection. Without the third line, the two spokes cannot reach each other.
Three networks that all talk need three connections. After section 1 you already have DEV-SHARED. A full mesh of four VPCs needs six. The formula is n × (n − 1) / 2. Three VPCs: three connections. Four VPCs: six.
Source: Three VPCs peered together, Amazon VPC. Three connections, one between each pair. Four VPCs follow the same pattern, with six lines. AWS does not publish a diagram that uses exactly VPC-DEV, VPC-HML, VPC-PROD, and VPC-SHARED. A custom drawing of those four boxes would make the count obvious. Until that drawing exists, use the table below and, to see the mesh actually explode, the official seven-VPC diagram.
Source: Multiple VPCs peered together, Amazon VPC. Seven VPCs, 21 connections.
Mesh for the four VPCs in this article:
| Connection | CIDRs the routes must cover |
|---|---|
| DEV-HML | 10.0.0.0/16 and 10.1.0.0/16 |
| DEV-PROD | 10.0.0.0/16 and 10.2.0.0/16 |
| DEV-SHARED | 10.0.0.0/16 and 10.3.0.0/16 |
| HML-PROD | 10.1.0.0/16 and 10.2.0.0/16 |
| HML-SHARED | 10.1.0.0/16 and 10.3.0.0/16 |
| PROD-SHARED | 10.2.0.0/16 and 10.3.0.0/16 |
The VPC-DEV route table, in this design, is no longer one extra row. It has three: HML, PROD, and SHARED, each with its own pcx-. When a fifth VPC arrives, each of the four existing ones gains another route and another peering connection. Operations grow with the product, not the sum.
Peering is still the right tool for a pair, or for a hub VPC that other VPCs reach without needing to reach each other (the "one peered with two" drawing, with no spoke-to-spoke traffic). It stops scaling well once every VPC must talk to every other VPC.
3. The same VPCs, now on a hub
AWS Transit Gateway is a Regional virtual router. It forwards packets by destination IP address (layer 3), not by the adapter's MAC address. VPCs no longer connect to each other. Each one connects once to the gateway. Traffic between them goes through that center. AWS calls this a hub-and-spoke topology: the Transit Gateway is the hub, each VPC is a spoke.
An attachment is how a resource joins the Transit Gateway. For this article, the attachment that matters is the VPC attachment. AWS also accepts Site-to-Site VPN, Direct Connect gateways, Connect (SD-WAN), Transit Gateway peering, and, in newer scenarios, network function attachments. We will not configure those other types here. They exist so you do not assume Transit Gateway only talks to VPCs.
When you create a VPC attachment, you pick one subnet per Availability Zone. AWS places an ENI in that subnet. That ENI is the Transit Gateway's entry and exit in that zone. A resource in a zone with no attachment cannot reach the gateway. The documentation recommends enabling more than one zone.
That attachment subnet does not have to be the application subnet. AWS's design guidance is a small subnet, for example /28, used only by Transit Gateway, in each zone you enable. Keep the network ACL on that subnet open. Workloads stay in their own subnets. Those workload subnets, in the same zone, still need a route to tgw- in the VPC route table. Without that route, the application's packet never reaches the gateway ENI.
Transit Gateway is highly available by design. A second gateway in the same Region is not what makes it available. You add another gateway for a separate routing domain, to limit the blast radius of a bad change, or for another Region (disaster recovery).
The attachment, by itself, still does not move any packets. You need two different kinds of route table.
VPC route table. It still sits on the subnet, as with Peering. Instead of target pcx-, the target is now the Transit Gateway (tgw-…). Without that route, the packet never leaves the VPC.
Transit Gateway route table. This is a different table, inside the gateway. It does not replace the VPC table. The VPC table answers: "should this packet go to the Transit Gateway?" The Transit Gateway table answers: "it arrived; which attachment do I send it to?"
By default the Transit Gateway comes with a default route table. That table is the default association table and the default propagation table. If you turn both options off at creation time, AWS does not create a default table. Each attachment is associated with exactly one gateway route table. The same attachment can propagate the VPC CIDR into one or more tables. Association is the map the attachment reads when a packet arrives from it. Propagation is the advertisement: "this network exists, install the CIDR in this table."
The official centralized-router diagram shows three VPCs and, in the same drawing, a VPN. The VPN is extra. This lab needs the hub and the spokes. Ignore the CIDRs in the screenshot (10.1, 10.2, 10.3, 10.99.99). Use 10.0, 10.1, 10.2, and 10.3 from the lab table.
Source: How AWS Transit Gateway works, Amazon VPC. The official drawing has three VPCs and a VPN. The fourth VPC in this article (VPC-SHARED) joins the same way: one more attachment, one more row in the gateway table. There is no official diagram with exactly these four boxes; the pattern is hub-and-spoke.
With four attachments, the default table, and default association and propagation enabled, the Transit Gateway route table looks like this:
| Destination | Target | Type |
|---|---|---|
10.0.0.0/16 | VPC-DEV attachment | propagated |
10.1.0.0/16 | VPC-HML attachment | propagated |
10.2.0.0/16 | VPC-PROD attachment | propagated |
10.3.0.0/16 | VPC-SHARED attachment | propagated |
In VPC-DEV, the workload subnet route table (no default route to the gateway):
| Destination | Target |
|---|---|
10.0.0.0/16 | local |
10.1.0.0/16 | tgw-… |
10.2.0.0/16 | tgw-… |
10.3.0.0/16 | tgw-… |
The centralized-router example in the docs uses 0.0.0.0/0 pointed at the Transit Gateway because that example also has a VPN: anything that is not local goes to the gateway and, from there, can continue to the office. With no VPN and no matching route on the gateway, a 0.0.0.0/0 to tgw- blackholes the VPC's internet traffic. That is why this lab lists the other VPCs' CIDRs one by one.
Path from 10.0.10.20 in DEV to 10.2.10.8 in PROD, now through the hub:
- The subnet table in DEV sees
10.2.0.0/16→tgw-…. - The packet enters the Transit Gateway on the DEV attachment.
- The gateway looks up the route table associated with that attachment. On the default table, it finds
10.2.0.0/16→ PROD attachment. - If the PROD attachment exists in the same Availability Zone the packet came from, the gateway uses that zone. If it does not, the gateway picks a zone where the PROD attachment is present.
- In PROD, the VPC table delivers
10.2.10.8as local. - The reply takes the reverse path: PROD subnet table → Transit Gateway → DEV attachment.
Four VPCs, four attachments. A fifth VPC needs a fifth attachment, a route on the gateway (often just CIDR propagation), and a row in the VPC tables that should reach it. You no longer manage n × (n − 1) / 2 connections. You manage n spokes.
The AWS VPC-to-VPC connectivity whitepaper shows the same hub, including Transit Gateways in more than one Region joined by peering. That drawing is the next step: a Transit Gateway is a Regional resource; another Region needs another gateway and a peering attachment between them. Treat it as background, not as the topology this article builds.
Source: AWS Transit Gateway, Amazon VPC Connectivity Options whitepaper.
4. Keep environments apart without removing the hub
In the previous scenario, DEV can reach PROD. In many accounts that is exactly what you do not want. Staging should not write to the production database. Production should not depend on a developer instance.
Transit Gateway does not isolate by magic. The default table, with every attachment associated and every CIDR propagated, is a single router: if you are attached, you can talk. Isolation comes from more than one route table on the gateway, choosing what each attachment reads and what each attachment advertises.
AWS calls this "isolated routers that use a shared service". Three workload VPCs do not talk to each other. All of them talk to a shared-services VPC (and, in the official drawing, also to a VPN).
Source: Example: Isolated VPCs with shared services, Amazon VPC. Ignore the CIDRs in this screenshot. In the official drawing, VPC A 10.1.0.0/16, VPC B 10.2.0.0/16, and VPC C 10.3.0.0/16 are isolated; VPC D 10.4.0.0/16 is shared services; there is a VPN 10.99.99.0/24. In this lab: A/B/C are VPC-DEV (10.0.0.0/16), VPC-HML (10.1.0.0/16), and VPC-PROD (10.2.0.0/16). D is VPC-SHARED (10.3.0.0/16). The 10.3 in the screenshot is isolated VPC C, not SHARED. The VPN in the screenshot is not part of the lab. The 0.0.0.0/0 that the docs put in the VPC tables for that example exists because of the VPN. With no VPN, do not point 0.0.0.0/0 at tgw-.
Two route tables on the Transit Gateway:
-
RT-ISOLATED, associated with the DEV, HML, and PROD attachments. -
RT-SHARED, associated with the SHARED attachment.
Propagation, following the same pattern as the documentation:
- DEV, HML, and PROD propagate only to
RT-SHARED. SHARED then learns10.0.0.0/16,10.1.0.0/16, and10.2.0.0/16. - SHARED propagates to
RT-ISOLATED. The three workload VPCs then learn10.3.0.0/16. The docs also propagate SHARED into the shared table. SHARED's own CIDR onRT-SHAREDis not what forwards the return path: traffic already inside SHARED uses the VPClocalroute.
RT-ISOLATED (what DEV, HML, and PROD read):
| Destination | Target | Type |
|---|---|---|
10.3.0.0/16 | VPC-SHARED attachment | propagated |
There is no row for 10.0.0.0/16, 10.1.0.0/16, or 10.2.0.0/16. A packet from DEV to PROD hits the gateway, the associated table has no route, and the traffic does not continue. The documentation describes that case as packets that "are blocked because there is no route for them in the transit gateway route table".
RT-SHARED (what SHARED reads):
| Destination | Target | Type |
|---|---|---|
10.0.0.0/16 | VPC-DEV attachment | propagated |
10.1.0.0/16 | VPC-HML attachment | propagated |
10.2.0.0/16 | VPC-PROD attachment | propagated |
These are the VPC route tables for this scenario. DEV, HML, and PROD only know SHARED via tgw-. SHARED knows all three.
VPC-DEV (HML and PROD look the same, with a different local CIDR):
| Destination | Target |
|---|---|
10.0.0.0/16 | local |
10.3.0.0/16 | tgw-… |
VPC-SHARED:
| Destination | Target |
|---|---|
10.3.0.0/16 | local |
10.0.0.0/16 | tgw-… |
10.1.0.0/16 | tgw-… |
10.2.0.0/16 | tgw-… |
Allowed path, DEV → SHARED (10.0.10.20 to 10.3.10.5):
- VPC table in DEV:
10.3.0.0/16→tgw-…. - The packet enters on the DEV attachment. The gateway reads
RT-ISOLATED. - Destination
10.3.10.5matches10.3.0.0/16→ SHARED attachment. - In SHARED, the VPC table delivers
10.3.10.5as local. - The reply: the VPC table in SHARED sees
10.0.0.0/16→tgw-…. - The packet enters on the SHARED attachment. The gateway reads
RT-SHARED, finds10.0.0.0/16→ DEV. - In DEV,
10.0.10.20is local.
Blocked path, DEV → PROD (10.0.10.20 to 10.2.10.8):
- The
VPC-DEVtable in this scenario has no route for10.2.0.0/16. The packet never leaves the VPC. - If someone adds that route by mistake, the packet reaches the gateway and
RT-ISOLATEDhas no10.2.0.0/16. The Transit Gateway does not forward it.
Two notes the documentation keeps repeating and beginners keep mixing up.
First: associate and propagate are not the same action. An attachment associated with RT-ISOLATED does not automatically install its CIDR in RT-ISOLATED. If DEV, HML, and PROD also propagated into RT-ISOLATED, the three would see each other again. Isolation in this scenario exists because the workload VPCs do not propagate into the table they themselves read.
Second: the VPC table and the Transit Gateway table work in sequence, not in parallel. The VPC decides whether the packet leaves toward tgw-. The Transit Gateway decides the destination attachment. Security groups and network ACLs still apply on the instance interface. A route on the gateway does not open port 3306 by itself.
AWS also lets you install a blackhole route in a Transit Gateway table: the prefix matches and the packet is dropped on purpose. That is extra insurance, not the main mechanism in this scenario.
5. Peering or Transit Gateway
Transit Gateway is not a strict upgrade from Peering. The right tool depends on the design.
| VPC Peering | Transit Gateway | |
|---|---|---|
| What it is | a one-to-one connection between two VPCs | a Regional virtual router, hub-and-spoke |
| Transitive routing | no. Without a third connection, the spokes do not talk | yes, among attachments that the gateway table can reach |
| Growth | n × (n − 1) / 2 connections for a full mesh | one attachment per VPC |
| Where you edit routes | VPC route tables only | VPC tables and gateway tables |
| Isolating environments | omit the peering for that pair | different tables, associations, and propagations |
| Region | intra-Region or inter-Region peering, directly between two VPCs | the gateway is Regional; another Region needs another gateway and peering between gateways |
| Overlapping CIDR | the peering connection fails; the path never exists | the attachment can exist; the overlapping CIDR is not propagated and the gateway does not route between those blocks |
| When it usually fits | a pair, or a hub VPC that other VPCs reach without needing to reach each other | many VPCs, hybrid (VPN / Direct Connect), segmentation on the same hub |
| Cost (the model, not a number) | no hourly attachment; data transfer applies, including when traffic crosses an Availability Zone | hourly per attachment and processing per GB sent to the gateway; see the pricing page |
Peering is still the better fit when the problem is "these two VPCs need to talk" and you do not expect a mesh. There is no hourly attachment. Bandwidth between the two VPCs does not take an extra hop through a managed router.
Transit Gateway starts to earn its keep when the question changes: "these ten VPCs, and the ones that will show up later, need one place for the policy of who talks to whom." Then the extra hop and the attachment charge are the cost of not keeping twenty-one pcx- connections.
Two limits worth knowing, both from the documentation, without turning the article into a quota sheet:
- A Transit Gateway cannot have two VPC attachments to the same VPC.
- The default quota is 5,000 attachments per gateway and 20 route tables per gateway, both adjustable. In a small account, the thing that bites first is a bad design: one default table with everything mixed together.
There is also an MTU difference. An intra-Region VPC peering connection supports up to 9001 bytes. Between VPCs, Direct Connect, Connect, and Transit Gateway peering, the gateway works with an MTU of 8500 bytes. VPN stays at 1500. When you migrate from Peering to Transit Gateway, a jumbo packet sent one way and returned the other can be dropped. AWS tells you to update both sides together.
What you have now
VPC-DEV, VPC-HML, VPC-PROD, and VPC-SHARED are four isolated networks until someone builds a path. Peering builds the path for one pair. With no transitivity, a mesh needs one connection per pair. Transit Gateway swaps that mesh for spokes on a hub. The VPC route table still decides whether the packet leaves. The Transit Gateway route table decides which attachment it goes to. Association and propagation, used with two tables, keep DEV, HML, and PROD apart and still let all three reach SHARED.
The service is not mandatory in a two-VPC account. It starts to make sense when most of the operational load is keeping pcx- connections, or when the policy "production does not talk to development, both talk to shared" needs to live in one place.
Official references used in this article: What is VPC peering?, How VPC peering connections work, VPC peering configurations, What is a transit gateway?, How AWS Transit Gateway works, Amazon VPC attachments, Transit gateway route tables, Transit gateway design best practices, AWS Transit Gateway quotas, AWS Transit Gateway in the multi-VPC whitepaper, Amazon VPC Connectivity Options, and AWS Transit Gateway pricing.










