AWS Lesson 52 of 123

Resilient AWS Direct Connect: Transit Gateway, BGP, and the SiteLink Mesh

In a nutshell

Imagine your company office and an AWS data centre. The public internet is the ordinary road network to reach it: usually fine, but with unpredictable traffic, no guaranteed travel time, and the occasional pile-up. AWS Direct Connect (DX) is a private leased highway straight from your building into AWS — consistent speed, low latency, and your packets never touch the public internet. The catch: one highway can still be closed by roadworks (an AWS maintenance) or an accident (a fibre cut). So a serious hybrid network builds two independent highways to two different interchanges, keeps an ordinary-road route (an encrypted VPN over the internet) as an emergency detour, and posts smart signage — the BGP routing protocol — so traffic instantly re-routes the moment a highway closes, and so cars going out and coming back always take the same highway (mismatched paths cause the head-on collisions we call asymmetric routing).

The Transit Gateway (TGW) is the big interchange on the AWS side: instead of wiring every one of your VPCs to on-prem separately, everything meets at one hub and the hub decides where each packet goes. A Direct Connect Gateway (DXGW) is the on-ramp that lets your private highways feed that interchange from any AWS Region. Put together, this lesson builds AWS’s maximum-resiliency model: four connections across two DX locations, all landing on a TGW through a DXGW, with an IPsec VPN backup on the same hub and BGP tuned so failover happens in under a second.

Level: Expert · Time: ~45 min

Prerequisites — this is an advanced networking lesson. You will get the most from it if you already understand VPCs, subnets, and route tables (see VPC deep dive), how a Transit Gateway hubs many VPCs together (see Transit Gateway multi-account architecture), and the basics of BGP (autonomous systems, prefixes, AS-path). If “BGP” and “/30 peering subnet” are new, skim a BGP primer first, then come back.

After this lesson you will be able to:

Direct Connect + Transit Gateway resilient connectivity

Read the diagram left to right: four connections across two DX locations become transit VIFs on a global Direct Connect Gateway, which associates to a regional Transit Gateway that fans out to every VPC — while a Site-to-Site VPN hangs off the same TGW as a heavily-prepended internet backup, and BGP + BFD (badge 6) decide how fast traffic moves when a link or an entire location fails.

A single Direct Connect circuit is a private 1/10 Gbps pipe with no SLA worth printing. The resiliency lives entirely in how you pair connections across locations and devices, how BGP converges when one fails, and whether you have an encrypted path to fall back to. This guide builds the maximum resiliency model end to end: four connections across two Direct Connect locations, transit VIFs landing on a Transit Gateway through a Direct Connect Gateway, BGP tuned for fast failover, and a Site-to-Site VPN backup riding the public internet.

First principles: what Direct Connect actually is (before the build)

The build steps below move fast because they assume you already know what each object is. If you are newer to hybrid networking, ground yourself here first — it is the “why” that makes the rest stick.

The problem DX solves. A Site-to-Site VPN over the internet is cheap and quick, but it inherits the internet’s weather: variable latency, occasional packet loss, and a hard throughput ceiling (~1.25 Gbps per tunnel). For a database replicating cross-site, a trading feed, or a chatty file protocol, that jitter is unacceptable. Direct Connect gives you a private, physical Ethernet handoff into the AWS network with consistent latency and dedicated bandwidth. It is not encrypted by itself and it is not automatically redundant — those are things you add, which is the entire point of this lesson.

The physical reality. Your router does not plug into AWS directly. Both you and AWS have equipment in the same colocation facility (a “DX location” such as an Equinix or CoreSite building). AWS gives you a Letter of Authorization and Connecting Facility Assignment (LOA-CFA); you hand it to the colo provider, who runs a cross-connect — a literal fibre patch cable — between the AWS cage and your cage (or your network provider’s cage). That cross-connect is the “connection.” Everything logical (VLANs, BGP, VIFs) rides on top of it.

Dedicated vs hosted — pick this before you order. There are two ways to obtain a connection, and they constrain everything downstream:

Dedicated connection Hosted connection
Ordered from AWS directly An AWS Direct Connect Partner
Port speeds 1, 10, or 100 Gbps (a full port) 50 Mbps → 25 Gbps (a slice of the partner’s port)
VIFs per connection Many (multiple private/public; one transit VIF, which then stands alone) Exactly one VIF
LAG (bundling) Yes (1–4 same-speed ports on one device) No
MACsec Yes, on capable 10/100 Gbps ports at supported locations No
Lead time Weeks (cross-connect + provisioning) Often days (partner already has the port)

For the maximum-resiliency TGW design in this lesson you want four dedicated connections (so you can run one transit VIF on each, use MACsec, and control the physical device/location diversity). Hosted connections are perfectly good for smaller or faster-to-stand-up needs, but a single hosted connection carrying a single VIF is not a resiliency story on its own.

Why BGP, not static routes. You could hard-code routes, but then a failed link is a manual outage. Direct Connect speaks BGP (Border Gateway Protocol) so the two sides advertise the networks they can reach and withdraw them when a link dies. That withdrawal is what makes failover automatic. Your router uses a private ASN (autonomous system number, e.g. 65000); the AWS side answers with the Amazon-side ASN you pick on the DXGW (e.g. 64512). BGP is the nervous system of everything that follows — get comfortable with AS-path, local-preference, and prefix length and the rest of this lesson is straightforward.

A worked example: one packet’s round trip

Make it concrete. An on-prem host 10.1.5.10 needs to reach an EC2 instance 10.20.3.40 in a VPC behind the Transit Gateway.

  1. On-prem lookup (outbound). Your router has learned 10.20.0.0/16 via BGP over the DX VIFs (the TGW’s VPC space, re-advertised as part of the 10.0.0.0/8 summary the DXGW sends). It has learned it on all four VIFs, but you set local-preference 200 on the two Location A VIFs, so the router prefers Location A. The packet leaves toward Location A, device 1.
  2. Across the cross-connect. The frame carries VLAN 101 (this transit VIF’s tag). If MACsec is on, the whole frame is encrypted at line rate on the wire between your router and the AWS device. It arrives at the AWS DX router.
  3. DXGW → TGW. The transit VIF hands the packet to the Direct Connect Gateway, which is associated with your Transit Gateway. The TGW consults its route table, finds 10.20.0.0/16 pointing at the VPC attachment, and forwards it into the VPC. The instance’s subnet route table sends it to 10.20.3.40. Delivered.
  4. The return trip (the part that bites people). The instance replies to 10.1.5.10. The TGW has learned 10.1.0.0/16 (your on-prem space) from BGP over the DXGW. Which of the four VIFs does AWS send it back on? AWS chose based on AS-path length — and because you prepended your ASN on the Location B VIFs, AWS sees Location A as the shorter path and returns traffic via Location A too. Both directions now agree on Location A. If they did not agree, a stateful firewall in front of the VPC would see the outbound SYN on one location and the inbound SYN-ACK on the other and silently drop the flow. That symmetry is the single most important routing outcome in the whole design.

Hold onto that round trip: every failover control in the later steps exists to keep step 1 and step 4 pointed at the same location, and to move both of them, fast, when that location fails.

1. Resiliency models and what the SLA actually covers

AWS publishes three resiliency models, and the SLA you can claim is a direct function of which one you build. The Direct Connect SLA (99.99% for the maximum model) is only honored if your topology matches the requirement.

Model Topology Survives SLA
Maximum Two DX locations, each with redundant devices Device failure and full location failure 99.99%
High One connection at each of two DX locations Full location failure, single connection failure 99.9%
Single (dev/test) Two connections at one location Single connection or device failure only None

The trap is the “high” model: two connections at the same location share a building and sometimes a single AWS router, so a maintenance event or fiber cut takes both down. For production hybrid, the maximum model is the only one that earns the 99.99% number.

The SLA measures availability of the service. If your BGP config blackholes traffic during a failover, the circuit was “up” and you still had an outage. Resiliency is a property of your routing, not just your cabling.

For the maximum model you order two connections at DX Location A (on separate AWS devices) and two more at DX Location B — four connections, four cross-connects, ideally on diverse fiber to each facility.

2. Connections, LAGs, and virtual interfaces decoded

Three layers stack on each physical port; conflating them is the most common design mistake.

VIF type Reaches Use with
Private VIF A single VPC via a VGW (or DX Gateway) One-VPC hybrid
Public VIF AWS public endpoints (S3, public APIs) over private fiber Avoiding the internet for public endpoints
Transit VIF A Transit Gateway via a Direct Connect Gateway Many VPCs / many regions

For a Transit Gateway design you want transit VIFs. A transit VIF attaches to a Direct Connect Gateway (DXGW), which in turn associates to one or more Transit Gateways. With four connections you get four transit VIFs and four BGP sessions, and the DXGW load-balances and fails over across them.

A hard limit: a Direct Connect connection supports at most one transit VIF, and on most port speeds cannot carry private or public VIFs alongside it. For a pure TGW design, make all four transit.

3. Step 1 - Order connections and stand up the Direct Connect Gateway

Order connections from the console or CLI; the cross-connect and Letter of Authorization (LOA-CFA) steps are manual. Request the connections first, on separate devices per location:

# Location A, device 1
aws directconnect create-connection \
  --location "EqDC2" \
  --bandwidth "10Gbps" \
  --connection-name "dx-locA-dev1" \
  --request-macsec-capable

# Location B, device 1 (diverse location)
aws directconnect create-connection \
  --location "CSSEA1" \
  --bandwidth "10Gbps" \
  --connection-name "dx-locB-dev1" \
  --request-macsec-capable

--request-macsec-capable only succeeds on MACsec-supported ports (dedicated 10/100 Gbps at supported locations); request it now, since you cannot retrofit a non-capable port. Repeat for the second device at each location, then download each LOA-CFA and hand it to the colocation provider for the cross-connect:

aws directconnect describe-loa \
  --connection-id "dxcon-aaaa1111" \
  --output text --query loaContent | base64 --decode > loa-locA-dev1.pdf

Once cross-connects are live and the ports show available, create the Direct Connect Gateway — a global, region-agnostic object and the anchor for the whole design. Its Amazon-side ASN is what AWS uses on the BGP sessions toward your router.

aws directconnect create-direct-connect-gateway \
  --direct-connect-gateway-name "dxgw-prod-global" \
  --amazon-side-asn 64512

Choose the Amazon-side ASN deliberately. It must differ from your on-prem ASN, and if you ever attach this DXGW to a Transit Gateway, the DXGW ASN and the TGW ASN must also be distinct. Picking from the private ASN range (64512-65534, or the 32-bit private range) and documenting it now avoids a painful renumber later, since the DXGW ASN is immutable after creation.

4. Step 2 - Associate the Transit Gateway and configure transit VIFs

Create the Transit Gateway (or reuse an existing one) and associate it to the DXGW. The association declares which CIDRs the TGW advertises out to on-prem via the allowed prefixes list — the single most important field in the whole build.

# Create the TGW with its own distinct ASN
aws ec2 create-transit-gateway \
  --description "tgw-prod" \
  --options "AmazonSideAsn=64513,DefaultRouteTableAssociation=enable,DefaultRouteTablePropagation=enable"

# Associate the TGW to the DXGW, declaring the prefixes the TGW will advertise to on-prem
aws directconnect create-transit-gateway-association \
  --direct-connect-gateway-id "dxgw-1234567890abcdef" \
  --gateway-id "tgw-0a1b2c3d4e5f6a7b8" \
  --add-allowed-prefixes-to-direct-connect-gateway "cidr=10.0.0.0/8"

The allowed-prefixes on a transit association are not a filter on inbound routes — they are the summaries the DXGW advertises from AWS to on-prem over every transit VIF. Advertise one clean summary (e.g. 10.0.0.0/8 covering all VPC space) rather than dozens of specifics, since the DXGW caps advertised prefixes.

Create one transit VIF per connection — each with its own VLAN, /30 peering subnet, and BGP session to the DXGW.

aws directconnect create-transit-virtual-interface \
  --connection-id "dxcon-aaaa1111" \
  --new-transit-virtual-interface '{
    "virtualInterfaceName": "tvif-locA-dev1",
    "vlan": 101,
    "asn": 65000,
    "mtu": 8500,
    "directConnectGatewayId": "dxgw-1234567890abcdef",
    "addressFamily": "ipv4",
    "amazonAddress": "169.254.100.1/30",
    "customerAddress": "169.254.100.2/30",
    "authKey": "your-bgp-md5-secret"
  }'

Details that matter:

5. Step 3 - Route propagation, allowed prefixes, and asymmetric routing

You now have BGP in both directions and need to make it deterministic.

Outbound from AWS (TGW to on-prem) is controlled by the allowed-prefixes on the TGW-DXGW association (Step 2); the DXGW advertises those summaries equally over all four transit VIFs. With DefaultRouteTablePropagation=enable, learned routes propagate to the TGW route table automatically.

Inbound to AWS (on-prem to TGW) is driven by what your routers advertise. To prefer Location A normally and fail to Location B, shape it with BGP attributes:

! Cisco IOS-XE: prefer Location A, prepend Location B
router bgp 65000
 address-family ipv4 unicast
  ! Location A: higher local-pref preferred for AWS-bound traffic
  neighbor 169.254.100.1 route-map LOCA-PRIMARY in
  ! Location B: prepend our ASN outbound so AWS prefers A
  neighbor 169.254.110.1 route-map LOCB-BACKUP out
!
route-map LOCA-PRIMARY permit 10
 set local-preference 200
!
route-map LOCB-BACKUP permit 10
 set as-path prepend 65000 65000

AWS path selection over Direct Connect goes longest prefix match, then AS_PATH length, then specific local routes. AWS ignores local-preference (your side’s attribute) and does not honor inbound MED across the DXGW reliably, so the durable lever for steering AWS-bound traffic is AS_PATH prepending on the secondary connections, plus a more-specific on the primary for a harder preference.

Asymmetric routing is the classic Direct Connect outage. If AWS returns traffic out Location B while you send out Location A, stateful firewalls drop the mismatched flows. The fix: make both directions agree on the same primary — higher local-pref inbound on A, prepend on B outbound — and keep prefix lengths symmetric per location rather than summarizing one and de-aggregating the other.

6. Step 4 - Encrypting the link: MACsec on the port vs IPsec over the VIF

Direct Connect is private but not encrypted by default. Two options operate at different layers:

Approach Layer Scope Requirements
MACsec (802.1AE) L2, on the port Entire connection, all VIFs MACsec-capable dedicated port; supported location; CKN/CAK keys
IPsec over the VIF L3, in a VPN tunnel A Site-to-Site VPN over the DX path Public VIF + VPN, or the VPN backup itself

MACsec is line-rate, point-to-point on the cross-connect, and the cleaner answer when both router and port support it (why we passed --request-macsec-capable in Step 1). Associate a MACsec secret — a Connection Key Name (CKN) and Connectivity Association Key (CAK) — to the connection:

aws directconnect associate-mac-sec-key \
  --connection-id "dxcon-aaaa1111" \
  --ckn "0011...your-ckn..." \
  --cak "1122...your-cak..." 

# Require encryption: unencrypted frames are dropped, not allowed through
aws directconnect update-connection \
  --connection-id "dxcon-aaaa1111" \
  --encryption-mode "must_encrypt"

Set encryption-mode to must_encrypt only after the key is confirmed on both ends; setting it before the peer is keyed drops the link. Use should_encrypt during cutover.

If MACsec is unavailable (a hosted connection, or a 1 Gbps port), encrypt at L3 by running a Site-to-Site VPN over a public VIF, or rely on the IPsec VPN backup below. You cannot run a VPN over a transit VIF.

7. The Site-to-Site VPN backup and BGP timer tuning

The encrypted, internet-based backup attaches to the same Transit Gateway, so failover is a routing decision, not a topology change. Create a Customer Gateway, then a VPN attachment to the TGW with dynamic BGP routing.

aws ec2 create-customer-gateway \
  --type ipsec.1 \
  --public-ip 203.0.113.10 \
  --bgp-asn 65000

aws ec2 create-vpn-connection \
  --type ipsec.1 \
  --customer-gateway-id "cgw-0abc123" \
  --transit-gateway-id "tgw-0a1b2c3d4e5f6a7b8" \
  --options '{"StaticRoutesOnly":false,"TunnelOptions":[{},{}]}'

The point of the backup is that it stays quiet until Direct Connect fails:

For failover speed, the constraint is BGP convergence. The default 90-second hold time is far too slow for production. Two levers:

  1. BFD (Bidirectional Forwarding Detection) on the DX VIFs. AWS supports BFD; with the AWS-side defaults (300 ms interval, multiplier 3), enabling it per VIF neighbor gives sub-second detection versus tens of seconds for BGP timers alone. This is the recommended approach.
  2. Tuned BGP timers where BFD is not available (the VPN). Lower keepalive/hold on your side; AWS negotiates the lower of the two.
! Enable BFD on the Direct Connect VIF neighbors for sub-second failover
router bgp 65000
 neighbor 169.254.100.1 fall-over bfd
 neighbor 169.254.110.1 fall-over bfd
!
interface ...
 bfd interval 300 min_rx 300 multiplier 3

With BFD on DX and a heavily-prepended VPN on the same TGW, a connection or location failure reconverges to the surviving DX path in well under a second, and a total DX failure falls to the VPN automatically.

Enterprise scenario

A payments platform ran the maximum model across two DX locations into a TGW, plus an IPsec VPN backup on the same TGW. During a planned AWS maintenance on one Location A device, both Location A VIFs went down as expected and traffic moved to Location B — but a chunk of flows from on-prem to a PCI VPC started timing out. The circuits were “up”; this was asymmetric routing. On-prem still sent AWS-bound traffic toward Location A’s surviving-but-draining path because of stale local-preference, while AWS, having lost the Location A BGP sessions, returned everything via Location B. The stateful firewalls in front of the PCI VPC saw SYN out one location and SYN-ACK in via the other, and silently dropped the half-open flows.

Root cause: they steered inbound (AWS-to-on-prem) with local-preference, which AWS ignores across the DXGW, and never made outbound (on-prem-to-AWS) agree. The durable fix was AS_PATH prepending on the Location B VIFs so AWS consistently preferred Location A, matched by higher local-pref inbound on A — both directions pinned to the same primary.

! Location B VIFs: prepend outbound so AWS prefers Location A, symmetric with inbound local-pref
route-map LOCB-BACKUP-OUT permit 10
 set as-path prepend 65000 65000 65000
!
router bgp 65000
 neighbor 169.254.110.1 route-map LOCB-BACKUP-OUT out
 neighbor 169.254.100.1 fall-over bfd
 neighbor 169.254.110.1 fall-over bfd

They also enabled BFD on every DX VIF, cutting failover detection from tens of seconds to sub-second. The lesson: a “healthy” circuit count proves nothing when both directions disagree on the primary path.

Going deeper

The build above gets a resilient design running. This section is for the engineer who owns it in production — the internals, the sharper levers, and the features the four steps glossed over.

Transit Gateway route tables: association vs propagation

The TGW is not one route table — it can hold many, and two different verbs decide behaviour. Confusing them is the most common TGW mistake:

DefaultRouteTableAssociation=enable and DefaultRouteTablePropagation=enable (set in Step 2) put every attachment into one shared table — fine for a flat network, dangerous for segmentation. To isolate, say, a PCI VPC so it can reach on-prem but not the other VPCs, you give it its own association table that propagates only the DXGW attachment, and you do not propagate the PCI attachment into the shared table. That is segmentation by route table, and it is why production landing zones disable the defaults and build tables per security zone. The multi-account patterns are covered in the Transit Gateway multi-account architecture lesson.

Every attachment type the hub accepts

A TGW is a router with five attachment kinds, and this design uses three of them:

Attachment What it connects Note
VPC A VPC (one ENI per AZ you enable) Routes are the VPC CIDR; no BGP
VPN A Site-to-Site VPN (Customer Gateway) Dynamic BGP or static; ECMP can aggregate tunnels
Direct Connect gateway A DXGW (and thus your transit VIFs) The private-path attachment in this build
Peering Another TGW, same or cross-Region No transitive routing through a peer; static routes only
Connect A GRE + BGP overlay on a VPC or DX attachment For SD-WAN / third-party routers wanting BGP

ECMP and appliance mode — two flags that decide symmetry

ECMP (equal-cost multi-path). When the TGW learns the same prefix over multiple paths with an equal cost, it can load-balance across them. For VPN, enabling ECMP lets multiple tunnels aggregate beyond the ~1.25 Gbps single-tunnel ceiling. For Direct Connect, the DXGW spreads flows across the transit VIFs whose BGP advertisements are equal — which is exactly why you advertise the same summary equally on all four VIFs and then bias with AS-path only where you want a preference.

Appliance mode (ApplianceModeSupport=enable on a VPC attachment) is the fix for the asymmetry problem when a stateful appliance sits inside a VPC — a firewall fleet spread across AZs behind a Gateway Load Balancer. Without it, the TGW hashes forward and return flows independently and can land them on different AZ appliances, breaking the stateful session. With appliance mode, the TGW keeps both directions of a flow pinned to the same AZ. If your PCI VPC does inline inspection (see Gateway Load Balancer inline inspection), turn this on — it is the intra-VPC twin of the on-prem AS-path symmetry you fought for over DX.

BGP levers AWS actually honours (beyond raw local-pref)

The core lesson is right that AWS ignores your local-preference attribute across the DXGW — but AWS exposes its own local-preference through BGP communities you tag on the routes you advertise. This is the precise, AWS-native way to steer AWS-to-on-prem traffic:

Community you tag Effect on AWS’s return path
7224:7100 Low local preference (least preferred)
7224:7200 Medium local preference
7224:7300 High local preference (most preferred)

Tag your primary-location advertisements 7224:7300 and your backup-location advertisements 7224:7100, and AWS prefers the primary for return traffic even before AS-path is consulted. AWS’s selection order is roughly: longest prefix match → local preference (from these communities) → shortest AS-path → prefer DX over VPN. AS-path prepending still works and is more portable across routers, so many teams use both belt-and-braces. There are also scope communities for public VIFs (7224:9100 local Region, 7224:9200 continent, 7224:9300 all public Regions) that bound how far AWS re-advertises your prefixes — irrelevant for private/transit VIFs but worth knowing exists.

Hard BGP limits worth memorising: your router may advertise up to 1,000 prefixes to AWS over a private or transit VIF — exceed it and the BGP session drops entirely (not just the extra routes). In the other direction AWS advertises within a cap too (100 prefixes for a VGW association; a transit association’s allowed-prefixes list is limited to 20 entries). This is the real reason the design advertises one 10.0.0.0/8 summary instead of every VPC CIDR — summarisation is a stability requirement, not a tidiness preference.

SiteLink: using AWS’s backbone as your WAN

The lesson title promises the “SiteLink mesh,” and here is where it earns its place. Normally a Direct Connect VIF only carries traffic between on-prem and AWS. SiteLink is a per-VIF feature (enableSiteLink / the console toggle) that lets two Direct Connect locations attached to the same DXGW send traffic directly to each other over the AWS global backbone, without hairpinning through a VPC or a Region. In practice that turns AWS’s backbone into your global WAN: a branch on DX in Singapore can reach a branch on DX in Frankfurt, office-to-office, at backbone quality, by enabling SiteLink on both VIFs. It is billed separately (an hourly SiteLink charge plus SiteLink data transfer), and you enable it only on the VIFs that need site-to-site reach. For a company consolidating an MPLS WAN onto AWS, SiteLink is often the feature that justifies the whole DX footprint.

The DX Gateway is what makes this scale across Regions

A single Direct Connect Gateway is a global object, and that is the unlock for many-VPC and multi-Region reach from one DX footprint:

Jumbo frames and the path-MTU trap

Step 2 set mtu: 8500 on the transit VIFs (9001 is the ceiling for a private VIF; 8500 is the max for a transit VIF because the TGW adds encapsulation overhead). Jumbo frames cut CPU and boost throughput for bulk transfer — but only if every hop end to end supports the larger MTU. One 1500-byte segment in the on-prem path and you get silent fragmentation or black-holed packets when Don’t-Fragment is set. Confirm the full path first, and remember the VPN backup tunnels are capped far lower (~1500, often 1300–1400 after IPsec overhead), so an application that only works at 8500 over DX may misbehave the moment it fails to the VPN.

The cost model, briefly

Two line items dominate and they are easy to under-budget: port-hours (you pay per connection-hour for all four dedicated ports, whether or not traffic flows — resiliency has a fixed monthly floor) and data transfer out over DX, which is billed per GB but at a lower rate than internet egress (one of DX’s quieter wins). Add SiteLink charges if enabled, and the VPN attachment’s hourly + data cost. The maximum-resiliency model is deliberately expensive at rest — four ports doing nothing most of the time — which is the price of a 99.99% SLA. Right-size by starting some connections smaller (1 Gbps) and growing, rather than dropping to two ports and losing the model.

Verify

Confirm BGP, prefixes, and failover behavior before declaring the design done.

# All four transit VIFs should be 'available' with 'up' BGP
aws directconnect describe-virtual-interfaces \
  --query "virtualInterfaces[].{name:virtualInterfaceName,state:virtualInterfaceState,bgp:bgpPeers[0].bgpStatus}" \
  --output table

# DXGW associations: confirm allowed prefixes and 'associated' state
aws directconnect describe-direct-connect-gateway-associations \
  --direct-connect-gateway-id "dxgw-1234567890abcdef" \
  --query "directConnectGatewayAssociations[].{tgw:associatedGateway.id,state:associationState,prefixes:allowedPrefixesToDirectConnectGateway}"

# TGW route table: on-prem prefixes should resolve to the DXGW attachment, not the VPN
aws ec2 search-transit-gateway-routes \
  --transit-gateway-route-table-id "tgw-rtb-0abc123" \
  --filters "Name=type,Values=propagated"

On the router side, confirm received routes show the expected AS_PATH (prepended from the secondary location) and that BFD sessions are up — show ip bgp neighbors <peer> received-routes and show bfd neighbors. Then test the failure modes deliberately:

Checklist

Monitoring and pitfalls

Direct Connect publishes metrics to CloudWatch under the AWS/DX namespace per connection: ConnectionState, ConnectionBpsEgress/Ingress, ConnectionPpsEgress/Ingress, light levels (ConnectionLightLevelTx/Rx), and CRC/error counters. Alarm on ConnectionState dropping below 1 and on light levels drifting — a degrading optic shows in light levels before the link fully fails.

aws cloudwatch put-metric-alarm \
  --alarm-name "dx-locA-dev1-down" \
  --namespace "AWS/DX" \
  --metric-name "ConnectionState" \
  --dimensions Name=ConnectionId,Value=dxcon-aaaa1111 \
  --statistic Minimum --period 60 --evaluation-periods 1 \
  --threshold 1 --comparison-operator LessThanThreshold

The pitfalls that bite in production:

Build to the maximum model, prove every failure mode with a real shutdown test, and keep the VPN quiet but ready. Resiliency you have not tested is just a diagram.

Practice challenges

Work these in order — they climb from “read the model” to “design the failover.” Each has a worked solution; try it before you open it. Commands are illustrative (no live AWS account is assumed); all account IDs and resource IDs are placeholders.

1. (Beginner) Name the model and its SLA. A team has two Direct Connect connections, both at the same DX location, on two separate AWS devices. What resiliency model is this, what does it survive, and what enhanced SLA can they claim?

<details><summary>Solution</summary>

This is the Development and Test (single-location) model. Two devices in one building survive a single connection or device failure, but not a full-location failure (fibre cut, power event, or maintenance affecting the whole facility). It earns no enhanced SLA — the 99.9% and 99.99% numbers require connections in more than one location. To reach 99.9% they need one connection at a second location (high model); for 99.99% they need two connections at each of two locations (maximum model).

Why: the SLA is a function of location diversity, not connection count — two links in one building is still one building. </details>

2. (Beginner) Pick the VIF type. You are attaching four dedicated connections to a Transit Gateway that fronts 30 VPCs across two Regions. Which VIF type do you create, and how many?

<details><summary>Solution</summary>

Create a transit VIF — one per connection, so four transit VIFs. Private VIFs reach a single VPC via a VGW and public VIFs reach AWS public endpoints; only a transit VIF attaches to a Direct Connect Gateway, which then associates to your TGW(s). The VIF count tracks your resiliency (four connections) not your VPC count (30) — the TGW fans out to all 30 VPCs behind the DXGW.

aws directconnect create-transit-virtual-interface \
  --connection-id "dxcon-aaaa1111" \
  --new-transit-virtual-interface '{"virtualInterfaceName":"tvif-locA-dev1","vlan":101,"asn":65000,"directConnectGatewayId":"dxgw-1234567890abcdef","addressFamily":"ipv4"}'

Why: a transit VIF is the only VIF type that speaks to a DXGW/TGW; a connection carries one transit VIF, so four connections = four transit VIFs. </details>

3. (Intermediate) Fix the prefix that breaks BGP. An engineer wants on-prem to receive every VPC route explicitly, so they add 1,400 individual /24s to what AWS advertises out. The BGP session drops entirely. Why, and what is the fix?

<details><summary>Solution</summary>

AWS advertises to on-prem within a hard cap, and your router accepts up to 1,000 prefixes over a private/transit VIF before the whole BGP session is torn down — not just the surplus routes. Advertising 1,400 specifics blows past it. The fix is summarisation: advertise one clean 10.0.0.0/8 (or a handful of aggregates) via the TGW-DXGW association’s allowed-prefixes list, which is itself capped (20 entries for a transit association).

aws directconnect create-transit-gateway-association \
  --direct-connect-gateway-id "dxgw-1234567890abcdef" \
  --gateway-id "tgw-0a1b2c3d4e5f6a7b8" \
  --add-allowed-prefixes-to-direct-connect-gateway "cidr=10.0.0.0/8"

Why: prefix caps are a stability control — one summary keeps the session up where hundreds of specifics kill it. </details>

4. (Intermediate) Make both directions agree. Traffic should normally use Location A. On-prem prefers A with local-preference 200, but during a test AWS keeps returning traffic via Location B and a stateful firewall drops flows. What is happening, and how do you pin AWS to Location A?

<details><summary>Solution</summary>

AWS ignores your local-preference across the DXGW — that attribute only steers your outbound. AWS’s return path is chosen by AS-path length (and its own local-preference communities). Because both locations advertise the same AS-path, AWS is free to pick B. Pin it by prepending your ASN on the Location B VIFs so A is the shorter path, and/or tag Location A advertisements with community 7224:7300 (high) and Location B with 7224:7100 (low):

route-map LOCB-BACKUP-OUT permit 10
 set as-path prepend 65000 65000 65000
 set community 7224:7100
!
route-map LOCA-PRIMARY-OUT permit 10
 set community 7224:7300

Why: both directions must pin the same primary or stateful devices drop the asymmetric half-flows — AS-path prepend + AWS local-pref communities are the levers AWS actually honours. </details>

5. (Advanced) Design sub-second failover. Your architect wants a device or location failure to reconverge in under a second, and a total DX loss to fall to the VPN automatically. List the two mechanisms and where each applies.

<details><summary>Solution</summary>

  1. BFD (Bidirectional Forwarding Detection) on every DX transit VIF neighbour. With AWS-side defaults (300 ms interval × 3 multiplier ≈ sub-second) it detects a dead link far faster than BGP’s 90-second hold timer.
  2. A heavily-prepended Site-to-Site VPN on the same TGW. AS-path prepend the VPN 3–4× so AWS prefers DX while any DX path is up; when all four DX VIFs withdraw, the TGW’s only remaining route to on-prem is the VPN attachment, so it fails over automatically.
router bgp 65000
 neighbor 169.254.100.1 fall-over bfd
 neighbor 169.254.110.1 fall-over bfd
!
interface ...
 bfd interval 300 min_rx 300 multiplier 3

Why: BFD gives fast detection on DX; the same-TGW prepended VPN gives an automatic routing fallback — failover becomes a route change, not a rebuild. </details>

6. (Advanced) Add office-to-office reach. A branch on DX in Singapore must reach a branch on DX in Frankfurt, at backbone quality, without hairpinning through a VPC or a Region. Which feature, and what is the constraint?

<details><summary>Solution</summary>

Enable SiteLink on both branches’ VIFs. SiteLink lets two Direct Connect locations attached to the same Direct Connect Gateway exchange traffic directly over the AWS global backbone — turning the backbone into your WAN, no VPC or Region in the path. Constraints: both VIFs must sit on the same DXGW, and SiteLink is billed separately (an hourly charge plus SiteLink data transfer), so enable it only on VIFs that need site-to-site reach.

aws directconnect update-virtual-interface-attributes \
  --virtual-interface-id "dxvif-locSG1" --enable-site-link true

Why: SiteLink is the DX feature purpose-built for on-prem-to-on-prem over AWS’s backbone — the TGW hubs VPCs, but SiteLink hubs sites. </details>

Common beginner mistakes

These are misconceptions about how the pieces work, distinct from the production pitfalls in “Monitoring and pitfalls” above. Each one is a wrong mental model and the right one to replace it with.

Glossary

AWSDirect ConnectTransit GatewayBGPHybridResiliency
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments