Week 3: Failover and Chaos Testing¶
Test Matrix Week 3¶
┌────┬────────────────────────────────────────────────────────┬─────────┐
│ ID │ Failover Test │ Pass │
├────┼────────────────────────────────────────────────────────┼─────────┤
│3.1 │ ExpressRoute circuit failure (primary → secondary) │ <30s │
│3.2 │ Azure VPN Gateway failover (primary → secondary inst) │ <60s │
│3.3 │ GCP Cloud Interconnect failure │ Reroute │
│3.4 │ Hub site MPLS failure (MPLS → DIA) │ <15s │
│3.5 │ Branch DIA failure (DIA → LTE) │ <20s │
│3.6 │ SD-WAN hub failure (Mumbai → Chennai hub) │ <45s │
│3.7 │ Umbrella PoP failure (primary → secondary PoP) │ <10s │
│3.8 │ Private endpoint failover (SQL HA test) │ <30s │
└────┴────────────────────────────────────────────────────────┴─────────┘
TEST 3.1: ExpressRoute Circuit Failure and Failover¶
#!/bin/bash
# er_failover_test.sh
echo "=== TEST 3.1: EXPRESSROUTE FAILOVER ==="
echo "WARNING: This test causes brief disruption to O365/Teams traffic"
echo "Recommended: Run during off-peak hours (maintenance window)"
echo ""
echo "--- BASELINE MEASUREMENT ---"
## Record current path and latency for Teams
BASELINE_LAT=$(ping -c 5 teams.microsoft.com 2>/dev/null | tail -1 | awk -F/ '{printf "%.0f", $5}')
BASELINE_PATH=$(ssh admin@mum-hub-01 "show ip route 52.112.0.0 | grep via" 2>/dev/null)
echo "Baseline Teams latency: ${BASELINE_LAT}ms"
echo "Baseline route: $BASELINE_PATH"
echo ""
echo "--- STEP 1: Disable PRIMARY ExpressRoute interface ---"
T_START=$(date +%s%3N)
ssh admin@mum-hub-01 "configure terminal; interface TenGigabitEthernet0/0/2.4001; shutdown; end"
echo "Primary ER disabled at: $(date)"
echo ""
echo "--- STEP 2: Monitor BGP failover ---"
for i in $(seq 1 10); do
ELAPSED=$(( $(date +%s%3N) - T_START ))
PRIMARY=$(ssh admin@mum-hub-01 "show bgp ipv4 unicast summary | grep 169.254.200.1" 2>/dev/null | awk '{print $10}')
SECONDARY=$(ssh admin@mum-hub-01 "show bgp ipv4 unicast summary | grep 169.254.200.5" 2>/dev/null | awk '{print $10}')
NEW_ROUTE=$(ssh admin@mum-hub-01 "show ip route 52.112.0.0 | grep via" 2>/dev/null)
echo " [${ELAPSED}ms] Primary BGP: $PRIMARY | Secondary BGP: $SECONDARY"
if echo "$NEW_ROUTE" | grep -q "169.254.200.5"; then
T_FAILOVER=$(( $(date +%s%3N) - T_START ))
echo ""
echo " ✅ FAILOVER COMPLETE in ${T_FAILOVER}ms"
echo " New route: $NEW_ROUTE"
break
fi
sleep 3
done
## Verify Teams still works via secondary path
FAILOVER_LAT=$(ping -c 5 teams.microsoft.com 2>/dev/null | tail -1 | awk -F/ '{printf "%.0f", $5}')
echo ""
echo "--- STEP 3: Verify service continuity ---"
echo " Teams latency during failover: ${FAILOVER_LAT}ms (baseline: ${BASELINE_LAT}ms)"
[[ "$FAILOVER_LAT" -lt 50 ]] && echo " ✅ Teams still operational via secondary ER" \
|| echo " ⚠️ Teams latency degraded during failover"
## Restore primary
echo ""
echo "--- STEP 4: Restore primary interface ---"
ssh admin@mum-hub-01 "configure terminal; interface TenGigabitEthernet0/0/2.4001; no shutdown; end"
sleep 35
RESTORED_ROUTE=$(ssh admin@mum-hub-01 "show ip route 52.112.0.0 | grep via" 2>/dev/null)
echo "$RESTORED_ROUTE" | grep -q "169.254.200.1" && echo " ✅ Primary path restored (LOCAL_PREF 200 wins)" \
|| echo " ⚠️ Primary route not restored: $RESTORED_ROUTE"
Pass Criteria: - Failover complete within 30 seconds (BGP hold-time 30s) - Teams voice MOS does not drop below 3.5 during failover - Primary route restoration automatic within 35 seconds
TEST 3.2: Azure VPN Gateway Failover¶
#!/bin/bash
## azure_vpn_failover_test.sh
echo "=== TEST 3.2: AZURE VIRTUAL WAN VPN GATEWAY FAILOVER ==="
echo ""
echo "--- Baseline: Azure SQL reachable via primary tunnel ---"
ssh admin@blr-isr-01 "show ip route 10.100.10.10" 2>/dev/null
BASELINE=$(ssh admin@blr-isr-01 "ping vrf 1 10.100.10.10 repeat 5 | tail -1" 2>/dev/null)
echo "Baseline: $BASELINE"
echo ""
echo "--- Disable primary tunnel to Azure VPN GW ---"
T_START=$(date +%s%3N)
ssh admin@blr-isr-01 "configure terminal; interface Tunnel200; shutdown; end"
echo "--- Monitor failover to secondary tunnel ---"
for i in $(seq 1 8); do
ELAPSED=$(( $(date +%s%3N) - T_START ))
T201=$(ssh admin@blr-isr-01 "show interfaces Tunnel201 | grep 'line protocol'" 2>/dev/null | grep -c "up")
ROUTE=$(ssh admin@blr-isr-01 "show ip route 10.100.10.10 | grep via" 2>/dev/null)
echo " [${ELAPSED}ms] T201: $( [[ $T201 -ge 1 ]] && echo 'UP' || echo 'down') | Route: $ROUTE"
if echo "$ROUTE" | grep -q "Tunnel201"; then
T_FAILOVER=$(( $(date +%s%3N) - T_START ))
echo " ✅ Failover to Tunnel201 in ${T_FAILOVER}ms"
break
fi
sleep 8
done
## Verify SQL still reachable
sleep 5
FAILOVER_PING=$(ssh admin@blr-isr-01 "ping vrf 1 10.100.10.10 repeat 5 | tail -1" 2>/dev/null)
echo " Azure SQL during failover: $FAILOVER_PING"
## Restore
ssh admin@blr-isr-01 "configure terminal; interface Tunnel200; no shutdown; end"
sleep 30
echo " ✅ Tunnel200 restored"
TEST 3.4: Hub MPLS Failure (MPLS → DIA)¶
#!/bin/bash
## mpls_failover_test.sh
echo "=== TEST 3.4: MPLS → DIA FAILOVER ==="
HUB="mum-hub-01"
## Baseline: all apps using MPLS for corporate
echo "--- Baseline corporate traffic path ---"
CORP_PATH=$(ssh admin@$HUB "show sdwan app-fwd cflowd flows | grep 10.252 | head -3" 2>/dev/null)
echo "$CORP_PATH"
## Disable MPLS transport
T_START=$(date +%s%3N)
echo "--- Disabling MPLS transport (color: mpls) ---"
ssh admin@$HUB "sdwan; interface TenGigabitEthernet0/0/0; no tunnel-interface; exit; exit" 2>/dev/null
## (Alternatively: shut the physical interface)
## ssh admin@$HUB "configure terminal; interface TenGigabitEthernet0/0/0; shutdown; end"
## Monitor BFD re-convergence
for i in $(seq 1 5); do
sleep 5
ELAPSED=$(( $(date +%s%3N) - T_START ))
DIA_FLOWS=$(ssh admin@$HUB "show sdwan app-fwd cflowd flows | grep 10.252 | grep dia | wc -l" 2>/dev/null)
echo " [${ELAPSED}ms] Corporate flows via DIA: $DIA_FLOWS"
[[ $DIA_FLOWS -gt 0 ]] && { echo " ✅ Traffic moved to DIA"; break; }
done
## Verify latency impact (DIA will be slower than MPLS)
FAILOVER_LATENCY=$(ssh admin@$HUB "ping vrf 1 10.252.32.1 repeat 5 | tail -1" 2>/dev/null)
echo " Latency to NJ hub via DIA: $FAILOVER_LATENCY"
## Restore MPLS
ssh admin@$HUB "configure terminal; interface TenGigabitEthernet0/0/0; no shutdown; end"
sleep 15
echo " ✅ MPLS restored"
TEST 3.5: Branch DIA Failure (DIA → LTE)¶
#!/bin/bash
## branch_dia_lte_failover.sh
echo "=== TEST 3.5: BRANCH DIA → LTE FAILOVER ==="
BRANCH="blr-isr-01"
## Baseline
echo "--- Baseline: Branch using DIA ---"
ssh admin@$BRANCH "show sdwan interface | grep -E '(GigabitEthernet0|Cellular)'" 2>/dev/null
## Disable DIA
T_START=$(date +%s%3N)
echo "--- Shutting DIA interface ---"
ssh admin@$BRANCH "configure terminal; interface GigabitEthernet0/0/0; shutdown; end" 2>/dev/null
## Monitor LTE takeover
for i in $(seq 1 8); do
sleep 5
ELAPSED=$(( $(date +%s%3N) - T_START ))
LTE=$(ssh admin@$BRANCH "show sdwan bfd sessions | grep lte | grep Up | wc -l" 2>/dev/null)
CTRL=$(ssh admin@$BRANCH "show sdwan control connections | grep ESTABLISHED | wc -l" 2>/dev/null)
echo " [${ELAPSED}ms] LTE BFD sessions: $LTE | Control connections: $CTRL"
[[ $LTE -gt 0 ]] && { echo " ✅ Branch operating on LTE backup"; break; }
done
## Verify internet still working via Umbrella over LTE
ssh admin@$BRANCH "ping 208.67.222.222 repeat 3 | tail -1" 2>/dev/null | \
grep -qv "0 success" && echo " ✅ Umbrella DNS reachable via LTE" || echo " ⚠️ Umbrella unreachable"
## Restore DIA
ssh admin@$BRANCH "configure terminal; interface GigabitEthernet0/0/0; no shutdown; end" 2>/dev/null
sleep 20
echo " ✅ DIA restored — SD-WAN will prefer DIA over LTE automatically"