Building Site-to-Site VPN Failover Between Branch and AWS
Build a dual-tunnel AWS Site-to-Site VPN with BGP failover across branch circuits, verify convergence time, and document rollback steps.

In this lesson
Table of Contents
Table of contents
Before you begin
- Working knowledge of IPsec and BGP fundamentals
- AWS IAM permissions for VPC and VPN resource creation
- Access to branch router or firewall CLI supporting BGP
Track this tutorial
Choose your current status and tick each safety check as you complete it. Sign in to sync progress between devices.
Current status
Tutorial stages
- Step 1 — Provision two Customer Gateways and a BGP-based VPN connection
- Step 2 — Configure branch routers with IPsec and BGP
- Step 3 — Force failover and time the convergence
0 of 3 stages complete
Before you apply the change
Confirm these production-safety controls during the tutorial.
#Operational requirement
#Pre-implementation access review
#Route table propagation verification
Before signing off, confirm route propagation is actually enabled on the target route table rather than assumed. A tunnel showing UP with BGP Established can still fail to insert routes if propagation was never switched on for that specific table, particularly when a VPC has several route tables and only one was updated during initial build.
1aws ec2 enable-vgw-route-propagation --route-table-id rtb-0a1b2c3d --gateway-id vgw-0bbb2222
2
3aws ec2 describe-route-tables --route-table-ids rtb-0a1b2c3d --query "RouteTables[].Routes"Check every subnet-associated route table that branch traffic could traverse, not just the one used during the lab build — a workload sitting in a subnet associated with an unmodified table will silently lose reachability during failover while everything else appears healthy.
#Evidence to retain
Capture the output of describe-route-tables immediately after enabling propagation and again after the failover test, showing the destination CIDR pointing at the correct VGW attachment ID in both states. Auditors reviewing the change ticket later will want to see the route source shown as propagated rather than static, confirming BGP — not a manually entered route — is driving the path.
#Health check dependency on the branch router
CloudWatch’s TunnelState metric reflects the IPsec tunnel state as seen from the AWS side; it does not confirm the branch router’s BGP process is healthy. A router that has exhausted its BGP table memory or is mid-reload can show a tunnel as cryptographically up while still failing to advertise routes. Pair the CloudWatch alarm with an independent reachability probe from a host inside the branch LAN, scheduled outside the router itself, so a router-level fault doesn’t also disable the thing meant to detect it.
#Symptom: alarm silent, users still affected
If users report an outage but no CloudWatch alarm has fired, check whether the affected subnet’s route table was excluded from propagation, per the section above, before assuming the alarm threshold is misconfigured. This is a distinct fault class from tunnel failure and won’t appear in TunnelState at all.
#Change-control record additions
Alongside the evidence already listed, record the exact route table IDs modified, the propagation enable/disable timestamps, and the identity of the engineer who ran the command. Where a route table serves production and non-production subnets together, note explicitly which subnets were in scope for this change, since a shared table is a common source of unintended blast radius during rollback.
#Rollback addition
If route propagation must be reverted, disable it on the specific route table before deleting the VPN connection object, and confirm static routes are restored where required, otherwise the affected subnets are left with no path at all rather than reverting to the prior known-good state.
1aws ec2 disable-vgw-route-propagation --route-table-id rtb-0a1b2c3d --gateway-id vgw-0bbb2222Before touching production routing, confirm the engineer’s IAM role has been scoped rather than inherited from a broader administrator policy. A common oversight is running these commands under a role that also holds ec2:DeleteRoute or ec2:ReplaceRoute against unrelated route tables, which turns a VPN build into an accidental blast-radius incident. Request a time-bound elevation through your identity provider, log the request ticket number against the change record, and confirm the elevation expires automatically rather than relying on someone remembering to revoke it.
#Segregation of duties
Whoever approves the change record should not be the same person executing the router configuration. On a two-person operations team this can feel bureaucratic, but the point is a second set of eyes checking the ASN allocation and PSK handling before anything touches the live VGW. Record the approver’s name, the ticket reference and the approval timestamp in the same document that holds the BGP summaries — auditors will ask for all three together, not separately.
#Configuration detail often missed
#Dead peer detection alignment
AWS generates specific DPD timeout and retry values per tunnel in the downloaded configuration file. If the branch router’s IPsec profile uses a locally defined DPD interval instead of the AWS-generated one, the tunnel can appear UP in the console while the router considers the peer dead, producing a black-hole state that ping alone won’t reveal until the hold timer expires. Pull the exact values with:
1show crypto isakmp policy
2show crypto session detailCompare the DPD interval and retry count against the AWS-supplied configuration file line by line before accepting the tunnel as correctly built.
#MTU and fragmentation
IPsec overhead reduces the effective MTU across the tunnel. Where the branch router doesn’t clamp TCP MSS, large transfers can succeed on ping but stall on file copies once encapsulated packets exceed path MTU. Set an explicit MSS clamp on the tunnel interface:
1interface Tunnel1
2 ip tcp adjust-mss 1387Confirm with a large-payload transfer test, not just ICMP, before declaring the tunnel production-ready.
#Monitoring and alerting
A tunnel that fails silently outside business hours is worse than one that fails loudly during a change window. Configure CloudWatch alarms against the TunnelState metric for both VPN connections, with a threshold that pages on-call after two consecutive missed data points rather than a single blip, which reduces noise from transient carrier-side maintenance.
#Threshold guidance
| Condition | Threshold | Action |
|---|---|---|
| Single tunnel down >5 minutes | Warning | Notify on-call, no page |
| Both tunnels down >2 minutes | Critical | Page on-call immediately |
| BGP session flapping >3 times/hour | Warning | Investigate DPD and circuit stability |
| Convergence time >90 seconds in test | Warning | Re-tune hold timers before sign-off |
Route the critical alarm through the same paging channel used for other production routing incidents so the on-call engineer doesn’t need to know this is a VPN-specific alert to respond correctly.
#Realistic failure symptoms during operation
#Slow convergence under load
Convergence measured during a quiet test window can differ from convergence during a genuine failure at peak traffic. If the branch router’s CPU is already under load handling other BGP peers or NAT translations, BGP hold-timer expiry detection can be delayed, pushing real-world failover past the 90-second figure captured in testing. Re-run the shutdown test during a representative traffic period at least once before final sign-off, and note the discrepancy if one exists.
#Route flapping after partial circuit degradation
A circuit that is degraded rather than fully down — intermittent packet loss instead of a clean outage — can cause the BGP session to flap repeatedly rather than fail over cleanly. This produces a worse user experience than a single clean cutover because traffic oscillates between tunnels. Watch for repeated Established/Idle transitions in show ip bgp summary output and treat more than three flaps within an hour as a circuit-quality issue requiring ISP escalation rather than a VPN configuration fault.
#Change-control record keeping
The change ticket should carry more than a pass/fail note. Attach the pre-change route table export, the post-change route table export, both BGP summary captures, the timestamped ping log, and the CloudWatch alarm configuration screenshot. Where the build deviates from the standard — for example a non-default ASN or a manually adjusted local-preference — record the reason inline in the ticket rather than only in router comments, since router comments are lost on a config reload.
#Escalation path
If convergence exceeds 90 seconds after two consecutive re-tests with correctly matched timers, escalate to the network engineering lead before attempting further timer tuning — repeatedly lowering hold timers without understanding the root cause risks session instability under normal conditions. If PSK mismatches recur after a Customer Gateway rebuild, escalate to whoever holds the secrets vault administration rights rather than regenerating credentials repeatedly, since repeated regeneration without process review tends to mask a deeper handover gap between infrastructure and network teams.
A branch office loses its primary circuit at 08:14 on a Monday morning. If the site-to-site VPN to AWS is pinned to a single tunnel on a single Customer Gateway, that branch is now cut off from every AWS-hosted workload — file shares, line-of-business apps, RADIUS. Tickets pile up, the on-call engineer gets paged, and someone asks why redundancy wasn’t built in from day one.
Your task as the newly hired engineer: build a dual-tunnel VPN across two Customer Gateways on two separate ISP circuits, get BGP failover working, and produce proof it actually converges before change management will sign off. This is a routing change to production. Treat it as one.
#Prerequisites
| Requirement | Detail |
|---|---|
| IAM permissions | ec2:CreateVpnConnection, ec2:CreateCustomerGateway, ec2:CreateVpnGateway, ec2:DescribeVpnConnections, route table modify rights |
| VPC setup | Attached VGW or Transit Gateway, at least two modifiable route tables |
| Branch circuits | Two public IPs on different ISPs, terminating on IPsec/BGP-capable routers |
| ASN | Private ASN 64512–65534, unique against anything already peered to the VGW |
| Change approval | Logged before touching production routing |
| Identity | MFA-enforced access under Entra ID or IAM — no shared credentials |
#Step 1 — Provision two Customer Gateways and a BGP-based VPN connection
Create one Customer Gateway per circuit, then a VPN connection using dynamic routing, not static routes.
1aws ec2 create-customer-gateway --type ipsec.1 --public-ip 203.0.113.10 --bgp-asn 65001 --device-name "Branch-ISP-A"
2
3aws ec2 create-customer-gateway --type ipsec.1 --public-ip 198.51.100.20 --bgp-asn 65001 --device-name "Branch-ISP-B"
4
5aws ec2 create-vpn-connection --type ipsec.1 --customer-gateway-id cgw-0aaa1111 --vpn-gateway-id vgw-0bbb2222 --options "{"StaticRoutesOnly":false}"Capture the JSON output: VpnConnectionId, tunnel outside IPs, pre-shared keys. PSKs go into a secrets vault, never into a ticket comment. Do not proceed until aws ec2 describe-customer-gateways shows both gateways as available.
#Step 2 — Configure branch routers with IPsec and BGP
Match the IKE version, DPD timers and encryption suite exactly as AWS generated them. Then bring up BGP per tunnel.

1router bgp 65001
2 neighbor 169.254.100.1 remote-as 64512
3 neighbor 169.254.100.1 timers 10 30
4 address-family ipv4
5 network 10.50.0.0 mask 255.255.255.0
6 neighbor 169.254.100.1 activatePrefer the primary circuit with a higher local-preference or lower MED; ISP-B stays passive backupEstablished, and the VPC route table should propagate 10.50.0.0/24 with the correct preference. Capture show ip bgp summary from both routers and a screenshot of the route table before moving on. Confirm both tunnels show UP in the AWS console first — do not simulate failure against a half-built tunnel.
#Step 3 — Force failover and time the convergence
Shut the tunnel interface, not the physical WAN link, so the test stays reversible.
1interface Tunnel1
2 shutdownRun continuous probes throughout:
1ping -t 10.60.0.15Expect traffic to shift to Tunnel2 inside the BGP hold-timer window — typically under 90 seconds with the timers above. Capture the ping output showing exact dropped packets and recovery timestamp, plus show ip bgp summary confirming Tunnel2 as active with correct AS path length. This is the evidence change management will ask for.
#Verification
Bring Tunnel1 back up and confirm traffic reverts to the primary path once BGP re-establishes and preference is restored. Re-check both tunnel states in the AWS console, confirm route table propagation matches expectations, and archive all captured evidence — JSON output, BGP summaries, ping logs — against the change ticket.

1show ip bgp summary
2aws ec2 describe-vpn-connections --vpn-connection-ids vpn-0123456789abcdef0#Failure Modes
- BGP sessions establish but routes never propagate — usually a missing
networkstatement or route table not associated with the VGW. - Failover takes far longer than expected — hold timers left at defaults (180 seconds) instead of the tuned 10/30 values.
- Both tunnels show UP but traffic still drops during the test — asymmetric routing because the branch LAN default route wasn’t updated to prefer the VPN path.
- PSK mismatch after a rebuild — someone regenerated the Customer Gateway without updating the router config, and the tunnel silently fails to rekey.
#Rollback
If failover testing causes unexpected outages, immediately bring Tunnel1 back up, verify BGP re-establishes, and revert any manual local-preference changes on the router. If the entire build is unstable, delete the VPN connection and Customer Gateway objects, restore the previous single-tunnel configuration from backup, and document why in the change ticket before reattempting.
1aws ec2 delete-vpn-connection --vpn-connection-id vpn-0123456789abcdef0
2aws ec2 delete-customer-gateway --customer-gateway-id cgw-0aaa1111#Operational Summary
The diagram below shows the intended failover path.
Rendering diagram...
A dual-tunnel, BGP-backed VPN turns a single-circuit outage from a full branch disconnection into a brief, self-healing reroute. The value isn’t the configuration itself — it’s the evidence trail: BGP summaries, route table screenshots and timed packet-loss logs that prove convergence works before production sign-off, and that give the next engineer on call something concrete to check when a circuit fails at 08:14 on a Monday.
Comments
Add a thoughtful note on Building Site-to-Site VPN Failover Between Branch and AWS. Comments are checked for spam and held for moderation before appearing.
Related articles
Enterprise Networking Fundamentals
Deploying Entra ID Conditional Access Without Locking Everyone Out
A staged, reversible method for enforcing MFA via Entra ID Conditional Access, covering break-glass accounts, Report-only validation, and rollback steps.
Enterprise Networking Fundamentals
Resolving Hybrid DNS Failures for Entra ID Hybrid-Joined Devices
A junior-engineer runbook for diagnosing and fixing DNS resolution failures on Entra ID hybrid-joined devices across on-premises AD and Azure Private DNS.
Enterprise IT Management
Tiered Admin Model: Killing Lateral Movement
How authentication silos, PAWs and Kerberos armoring enforce privileged access tiering to stop pass-the-hash lateral movement across AD tiers.
Tech Fundamentals
Fixing UEFI Secure Boot Chain-of-Trust Failures
How PK, KEK, db, dbx, shim and MOK layers interact, and the mokutil, sbsign, and sbctl steps that repair a broken UEFI trust chain.
Learn More About KBY
About KBY
Learn about our mission, editorial standards, and commitment to trusted engineering knowledge.
Why Trust KBY
Explore the processes and policies that ensure our publications are accurate, useful, and responsible.
Newsletter
Get our latest editorial publications, research and practical insights sent directly to your inbox.
Was this useful?
Build practical engineering skills.
Receive new lessons, learning paths, practical exercises and early-career guidance.