Hands-On Project: Disaster Recovery Drill¶
Plan and execute a disaster recovery drill to validate backup and recovery procedures.
Estimated Time: 4-6 hours Difficulty: Advanced Prerequisites: Existing cloud infrastructure, understanding of backup concepts, production-like environment
Architecture Overview¶
DR Patterns (increasing cost and complexity):
1. Backup and Restore
Primary Region --> Backups (S3/GCS/Azure Storage) --> Restore in DR Region
RTO: Hours | RPO: Hours
2. Pilot Light
Primary Region (full stack) --> DR Region (minimal: DB replica, AMIs ready)
RTO: 30-60 min | RPO: Minutes
3. Warm Standby
Primary Region (full stack) --> DR Region (scaled-down running copy)
RTO: 10-30 min | RPO: Seconds-Minutes
4. Active-Active (Multi-Region)
Region A (full stack) <--> Region B (full stack) with GSLB
RTO: ~0 | RPO: ~0
Step 1: Document RTO and RPO¶
Define Recovery Objectives¶
| System | RTO (Recovery Time) | RPO (Recovery Point) | DR Pattern | Priority |
|---|---|---|---|---|
| Customer-facing API | 15 minutes | 1 minute | Warm Standby | P1 |
| Database | 30 minutes | 5 minutes | Cross-region replica | P1 |
| Admin dashboard | 2 hours | 1 hour | Pilot Light | P2 |
| Batch processing | 4 hours | 24 hours | Backup/Restore | P3 |
| Static website | 10 minutes | N/A (immutable) | Active-Active CDN | P1 |
Document Dependencies¶
Customer API
+-- Database (PostgreSQL) - Cross-region replica
+-- Cache (Redis) - Recreate from DB
+-- Secrets Manager - Replicated
+-- DNS (Route 53) - Global service
+-- Certificate (ACM) - Must exist in DR region
+-- Container Images (ECR) - Cross-region replication
Step 2: Verify Backups¶
Database Backups¶
AWS RDS
# List automated backups
aws rds describe-db-instance-automated-backups \
--db-instance-identifier my-database
# List manual snapshots
aws rds describe-db-snapshots \
--db-instance-identifier my-database
# Verify cross-region snapshot copies
aws rds describe-db-snapshots --region us-west-2 \
--query 'DBSnapshots[?SourceRegion==`us-east-1`]'
# Check read replica status
aws rds describe-db-instances --db-instance-identifier my-database-replica-west \
--query 'DBInstances[0].{Status:DBInstanceStatus,ReplicaLag:StatusInfos}'
Azure SQL
# Check backup status
az sql db show --resource-group myRG --server myserver --name mydb \
--query '{backupRetention:earliestRestoreDate}'
# List long-term retention backups
az sql db ltr-backup list --resource-group myRG --server myserver --database mydb
GCP Cloud SQL
# List backups
gcloud sql backups list --instance my-instance
# Check replica status
gcloud sql instances describe my-replica --format="get(replicaConfiguration)"
Storage Backups¶
# AWS - Verify S3 cross-region replication
aws s3api get-bucket-replication --bucket my-bucket
# AWS - Check S3 versioning
aws s3api get-bucket-versioning --bucket my-bucket
# Azure - Check storage account replication
az storage account show --name mystorageacct --query '{sku:sku.name,replication:primaryEndpoints}'
# GCP - Check dual-region or multi-region bucket
gsutil ls -L -b gs://my-bucket | grep "Location"
Infrastructure as Code¶
# Verify Terraform state is backed up
aws s3 ls s3://my-terraform-state-bucket/ --recursive
# Verify container images are replicated
aws ecr describe-repositories --region us-west-2
# Verify secrets are replicated
aws secretsmanager list-secrets --region us-west-2
Step 3: Simulate Failure¶
Simulation Options (choose one)¶
Option A: Database Failover Test
# AWS - Force failover of Multi-AZ RDS
aws rds reboot-db-instance --db-instance-identifier my-database --force-failover
# Azure - Failover Azure SQL
az sql db failover --resource-group myRG --server myserver --name mydb
# GCP - Promote replica
gcloud sql instances promote-replica my-replica
Option B: Region Failure Simulation
# Simulate by routing all traffic away from primary region
# Update DNS to point to DR region
aws route53 change-resource-record-sets --hosted-zone-id ZONE_ID \
--change-batch '{
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "api.example.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "DR_LB_ZONE_ID",
"DNSName": "dr-alb.us-west-2.elb.amazonaws.com",
"EvaluateTargetHealth": true
}
}
}]
}'
Option C: Application Failure Simulation
# Scale down the primary application to zero
kubectl scale deployment my-app --replicas=0 -n production
# Or terminate instances in the primary ASG
aws autoscaling set-desired-capacity --auto-scaling-group-name primary-asg --desired-capacity 0
Step 4: Execute Failover¶
Failover Runbook¶
Phase 1: Detect and Declare (0-5 minutes) 1. Monitoring alerts trigger (automated) 2. On-call engineer confirms the outage is not transient 3. Incident commander declares DR activation 4. Notify stakeholders via status page
Phase 2: Activate DR Infrastructure (5-30 minutes)
# 1. Promote database replica (if not auto-failover)
aws rds promote-read-replica --db-instance-identifier my-database-replica-west
# 2. Scale up DR compute resources
aws autoscaling set-desired-capacity \
--auto-scaling-group-name dr-asg --desired-capacity 3
# Or scale up Kubernetes deployment in DR cluster
kubectl scale deployment my-app --replicas=3 -n production \
--context dr-cluster
# 3. Verify application health in DR region
curl -f https://dr-alb.us-west-2.elb.amazonaws.com/health
# 4. Update DNS to DR region
aws route53 change-resource-record-sets --hosted-zone-id ZONE_ID \
--change-batch file://failover-dns.json
Phase 3: Validate (30-60 minutes)
# Run smoke tests against DR endpoint
./scripts/smoke-tests.sh --endpoint https://api.example.com
# Verify data integrity
./scripts/data-integrity-check.sh
# Check monitoring in DR region
# - Application metrics flowing
# - Error rates normal
# - Latency acceptable
Step 5: Validate Recovery¶
Validation Checklist¶
# API responds correctly
curl -s https://api.example.com/health | jq .
# Authentication works
curl -s -H "Authorization: Bearer $TOKEN" https://api.example.com/me | jq .
# Data is consistent
# Compare record counts or checksums
psql -h dr-database -c "SELECT COUNT(*) FROM orders WHERE created_at > NOW() - INTERVAL '1 hour'"
# All services are communicating
kubectl get pods -n production --context dr-cluster
kubectl logs -l app=my-app -n production --context dr-cluster --tail=50
Performance Validation¶
# Check response times are within SLA
curl -w "DNS: %{time_namelookup}s, Connect: %{time_connect}s, Total: %{time_total}s\n" \
-o /dev/null -s https://api.example.com/health
# Run a light load test
# Use a tool like k6, vegeta, or hey
hey -n 1000 -c 10 https://api.example.com/health
Step 6: Document Lessons Learned¶
Post-Drill Report Template¶
# DR Drill Report - [Date]
## Summary
- Drill type: [Region failover / Database failover / Application failover]
- Start time: [HH:MM UTC]
- Recovery time achieved: [X minutes]
- RPO achieved: [X minutes of data]
## Objectives Met
- [ ] RTO target of [X minutes] - Actual: [Y minutes]
- [ ] RPO target of [X minutes] - Actual: [Y minutes]
- [ ] All critical services recovered
- [ ] Data integrity verified
- [ ] Monitoring operational in DR region
## Issues Found
1. [Issue description] - [Impact] - [Action item]
2. [Issue description] - [Impact] - [Action item]
## Runbook Updates Needed
- [Step X needs clarification]
- [Missing step: Y]
## Action Items
| Item | Owner | Due Date | Priority |
|---|---|---|---|
| Fix backup replication lag | DBA team | [date] | High |
| Update DNS TTL to 60s | Platform team | [date] | Medium |
| Add missing monitoring in DR | SRE team | [date] | High |
## Participants
- Incident Commander: [name]
- Database: [name]
- Application: [name]
- Networking: [name]
DR Patterns in Detail¶
Pattern 1: Backup and Restore¶
Primary Region DR Region (inactive)
[App] -> [DB] (nothing running)
|
[Backups] ---------> [S3/GCS cross-region copy]
|
(on activation, restore)
[App] <- [Restored DB]
When to Use: Non-critical systems, cost-sensitive, RTO of hours is acceptable Cost: Lowest - only paying for storage of backups Key Actions: Regular backup testing, automated restore scripts
Pattern 2: Pilot Light¶
Primary Region DR Region (minimal)
[App (3 replicas)] (no app running)
[DB Primary] --------replica-----> [DB Replica]
[AMIs/Images] [AMIs/Images copied]
When to Use: Important systems, need faster recovery than backup/restore Cost: Low - only DB replica and stored images Key Actions: Keep images updated, automate scaling of compute on activation
Pattern 3: Warm Standby¶
Primary Region DR Region (scaled down)
[App (3 replicas)] [App (1 replica)]
[DB Primary] --------replica-----> [DB Replica]
[LB (active)] [LB (standby)]
When to Use: Business-critical systems, RTO under 30 minutes Cost: Medium - running minimal infrastructure Key Actions: Regular traffic testing to DR, automated scaling
Pattern 4: Active-Active¶
Region A Region B
[App (3 replicas)] [App (3 replicas)]
[DB Primary] <----replication----> [DB Primary]
[LB (active)] [LB (active)]
\ /
\--------- GSLB (DNS) --------/
When to Use: Mission-critical, zero downtime requirement Cost: Highest - full duplicate infrastructure Key Actions: Conflict resolution strategy, data consistency checks
Runbook Template¶
# DR Activation Runbook
## Prerequisites
- [ ] DR credentials accessible and tested
- [ ] Runbook reviewed within last 30 days
- [ ] DR region infrastructure baseline verified
## Step 1: Declare DR Event
- [ ] Confirm outage is not transient (wait 5 minutes)
- [ ] Page incident commander
- [ ] Update status page
## Step 2: Database
- [ ] Promote read replica: `[exact command]`
- [ ] Verify promotion: `[exact command]`
- [ ] Update connection strings if needed
## Step 3: Application
- [ ] Scale DR compute: `[exact command]`
- [ ] Verify health checks pass: `[exact command]`
- [ ] Verify application logs show normal operation
## Step 4: Traffic Cutover
- [ ] Update DNS: `[exact command]`
- [ ] Wait for propagation (check with `dig`)
- [ ] Verify traffic flowing to DR: check LB metrics
## Step 5: Validate
- [ ] Run smoke tests: `[exact command]`
- [ ] Verify data integrity
- [ ] Confirm monitoring is active
- [ ] Notify stakeholders of recovery
## Rollback (return to primary)
- [ ] Resync data from DR to primary
- [ ] Verify primary health
- [ ] Gradually shift traffic back
- [ ] Rebuild DR replica
Verification Checklist¶
- RTO and RPO targets are documented for all systems
- Backups are verified and restorable
- Failover was executed within the target RTO
- Data loss was within the target RPO
- All critical services function correctly in DR
- Monitoring and alerting work in DR region
- Lessons learned are documented with action items
- Runbook is updated based on drill findings