Hybrid Networking: Direct Connect & Transit Gateway Together
Enterprise networks rarely live entirely in one VPC or entirely in the cloud. They span a data center, dozens of VPCs, and often several regions.
Search across all documentation pages
Enterprise networks rarely live entirely in one VPC or entirely in the cloud. They span a data center, dozens of VPCs, and often several regions.
Two AWS building blocks carry most of that weight. Direct Connect gives you a dedicated physical link into AWS. Transit Gateway gives you a routing hub that connects many VPCs and your on-premises network without a tangle of point-to-point links.
This page explains how the two compose, and - importantly for an SDK developer - which parts you actually create in code versus which parts are physical and ordered out of band.
Start with what each piece is on its own.
A Direct Connect connection is a physical Ethernet port at an AWS Direct Connect location, cross-connected to your equipment or a partner's. It carries no traffic by itself. To move packets you create one or more virtual interfaces on top of it: a private VIF reaches a VPC, a public VIF reaches AWS public services, and a transit VIF reaches a Transit Gateway through a Direct Connect gateway.
A Transit Gateway is a regional router in the cloud. You create it once, then attach things to it: VPCs, Site-to-Site VPN connections, peering to Transit Gateways in other regions, and Direct Connect (via a Direct Connect gateway). Every attachment can exchange routes with every other, governed by Transit Gateway route tables.
Neither replaces the other. Direct Connect is about the pipe - private, dedicated bandwidth. Transit Gateway is about the routing - who can reach whom, across many networks.
The join between the two is the part people find confusing, so trace it end to end.
The SDK owns steps 2 through 5. The transit VIF, the Direct Connect gateway, its association with the Transit Gateway, and the VPC attachments are all API calls. Here is the logical join - creating the Direct Connect gateway and associating it with the Transit Gateway.
# --- Python (boto3) ---
import boto3
dx = boto3.client("directconnect", region_name="us-east-1")
dxgw = dx.create_direct_connect_gateway(
directConnectGatewayName="corp-dxgw", amazonSideAsn=64512,
)
dxgw_id = dxgw["directConnectGateway"]["directConnectGatewayId"]
dx.create_direct_connect_gateway_association(
directConnectGatewayId=dxgw_id,
gatewayId="tgw-0abc123", # the Transit Gateway
addAllowedPrefixesToDirectConnectGateway=[{"cidr": "10.100.0.0/16"}],
)// --- TypeScript (AWS SDK v3) ---
import {
DirectConnectClient, CreateDirectConnectGatewayCommand,
CreateDirectConnectGatewayAssociationCommand,
} from "@aws-sdk/client-direct-connect";
const dx = new DirectConnectClient({ region: "us-east-1" });
const dxgw = await dx.send(new CreateDirectConnectGatewayCommand({
directConnectGatewayName: "corp-dxgw", amazonSideAsn: 64512,
}));
const dxgwId = dxgw.directConnectGateway?.directConnectGatewayId;
await dx.send(new CreateDirectConnectGatewayAssociationCommand({
directConnectGatewayId: dxgwId,
gatewayId: "tgw-0abc123", // the Transit Gateway
addAllowedPrefixesToDirectConnectGateway: [{ cidr: "10.100.0.0/16" }],
}));Notice this call succeeds even if the physical cross-connect is not yet live. The API models the logical relationship; packets only flow once the port is up and BGP is established. That gap - working API calls over a link that is not physically ready - is the single most common source of confusion for SDK developers new to Direct Connect.
The reason to compose these two, rather than run a mesh of VPN tunnels, is scale.
Without a Transit Gateway, every VPC that needs on-premises access needs its own private VIF, and Direct Connect has a per-connection VIF limit. Add a region and you multiply the problem. With the composition above, one transit VIF and one Direct Connect gateway serve every VPC attached to the Transit Gateway. You add a VPC by creating one attachment, not by touching the physical link at all.
# --- Python (boto3) ---
import boto3
ec2 = boto3.client("ec2", region_name="us-east-1")
att = ec2.create_transit_gateway_vpc_attachment(
TransitGatewayId="tgw-0abc123",
VpcId="vpc-0newapp",
SubnetIds=["subnet-0a", "subnet-0b"],
)
print(att["TransitGatewayVpcAttachment"]["TransitGatewayAttachmentId"])// --- TypeScript (AWS SDK v3) ---
import { EC2Client, CreateTransitGatewayVpcAttachmentCommand } from "@aws-sdk/client-ec2";
const ec2 = new EC2Client({ region: "us-east-1" });
const att = await ec2.send(new CreateTransitGatewayVpcAttachmentCommand({
TransitGatewayId: "tgw-0abc123",
VpcId: "vpc-0newapp",
SubnetIds: ["subnet-0a", "subnet-0b"],
}));
console.log(att.TransitGatewayVpcAttachment?.TransitGatewayAttachmentId);For global reach, you peer Transit Gateways across regions, and a single Direct Connect gateway can associate with Transit Gateways in multiple regions - so one physical link in one metro can reach VPCs on other continents. Availability comes from a second Direct Connect connection (ideally at a second location) plus a Site-to-Site VPN as a cheap backup path, all attached to the same hub. Those patterns each get their own page in this section.
Direct Connect is a dedicated physical link from on-premises into AWS. Transit Gateway is a regional cloud router that connects many VPCs and network attachments. One is the pipe, the other is the routing hub.
Through a Direct Connect gateway. You create a transit VIF on the DX connection, create a Direct Connect gateway, and associate that gateway with the Transit Gateway.
No. The SDK provisions logical constructs - VIFs, gateways, associations, attachments. The physical port and cross-connect are ordered separately from AWS or a Direct Connect partner.
A single transit VIF and Direct Connect gateway can reach every VPC attached to the Transit Gateway. You add VPCs with one attachment call rather than consuming a VIF and touching the physical link.
No. It is a global resource that can associate with Transit Gateways or virtual gateways in multiple regions, so one physical link can reach VPCs in several regions.
BGP exchanges routes across the transit VIF. On-premises advertises its prefixes and learns the VPC CIDRs, subject to the allowed prefixes on the association and Transit Gateway route-table propagation.
Not fully. A single connection is a single point of failure. Add a second connection at another location and a Site-to-Site VPN backup, all attached to the same Transit Gateway.
Yes, and that trips people up. Creating VIFs, gateways, and associations succeeds against the API, but packets only flow once the cross-connect is up and BGP is established.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Reviewed by Chris St. John·Last updated Jul 23, 2026