Lab 5: Simulación de Incidente
Lab 5: Simulación de Incidente
No hay código Terraform nuevo en este lab — simulamos la caída utilizando la AWS CLI, obteniendo los parámetros necesarios a partir de los outputs exportados por los módulos de Terraform.
Paso 1: Cargar variables desde el estado Terraform
source ~/route53-arc-tf/global.env
# Outputs del Lab 3 (ARC)
cd ~/route53-arc-tf/03_arc
export PRIMARY_RC_ARN=$(terraform output -raw primary_rc_arn)
export SECONDARY_RC_ARN=$(terraform output -raw secondary_rc_arn)
export CLUSTER_ENDPOINT=$(terraform output -json arc_cluster_endpoints \
| python3 -c "import json,sys; print(json.load(sys.stdin)[0]['Endpoint'])")
# Outputs del Lab 1 (EC2)
cd ~/route53-arc-tf/01_primary
export EC2_ID=$(terraform output -raw ec2_instance_id)
export PRIMARY_ALB_DNS=$(terraform output -raw alb_dns_name)
# Outputs del Lab 4 (Automation)
cd ~/route53-arc-tf/04_automation
export ALARM_NAME=$(terraform output -raw alarm_name)
export LAMBDA_NAME=$(terraform output -raw lambda_name)
echo "=== Estado inicial ==="
echo "ALB DNS: $PRIMARY_ALB_DNS"
echo "EC2 ID: $EC2_ID"
echo "Alarm: $ALARM_NAME"
# Verificar Routing Controls
echo ""
aws route53-recovery-cluster get-routing-control-state \
--routing-control-arn $PRIMARY_RC_ARN \
--endpoint-url $CLUSTER_ENDPOINT --region $AWS_REGION \
--query 'RoutingControlState' --output text | xargs -I{} echo "Primario: {}"
aws route53-recovery-cluster get-routing-control-state \
--routing-control-arn $SECONDARY_RC_ARN \
--endpoint-url $CLUSTER_ENDPOINT --region $AWS_REGION \
--query 'RoutingControlState' --output text | xargs -I{} echo "Secundario: {}"Simulación A: Forzar alarma CloudWatch (inmediato)
echo "=== SIMULACIÓN A: Forzando alarma CloudWatch ==="
echo "Hora: $(date)"
aws cloudwatch set-alarm-state \
--alarm-name $ALARM_NAME \
--state-value ALARM \
--state-reason "Simulación de incidente – AWS Workshop Terraform Workshop" \
--region $AWS_REGION
echo "⏳ Esperando que Lambda reaccione..."
sleep 15
# Verificar resultado
echo ""
echo "--- Routing Controls post-failover ---"
aws route53-recovery-cluster get-routing-control-state \
--routing-control-arn $PRIMARY_RC_ARN \
--endpoint-url $CLUSTER_ENDPOINT --region $AWS_REGION \
--query 'RoutingControlState' --output text | xargs -I{} echo "Primario: {} (esperado: Off)"
aws route53-recovery-cluster get-routing-control-state \
--routing-control-arn $SECONDARY_RC_ARN \
--endpoint-url $CLUSTER_ENDPOINT --region $AWS_REGION \
--query 'RoutingControlState' --output text | xargs -I{} echo "Secundario: {} (esperado: On)"Ver logs de Lambda:
LOG_GROUP="/aws/lambda/$LAMBDA_NAME"
STREAM=$(aws logs describe-log-streams \
--log-group-name $LOG_GROUP \
--order-by LastEventTime --descending --max-items 1 \
--region $AWS_REGION \
--query 'logStreams[0].logStreamName' --output text)
aws logs get-log-events \
--log-group-name $LOG_GROUP \
--log-stream-name "$STREAM" \
--region $AWS_REGION \
--query 'events[*].message' --output text | tail -15Simulación B: Detener nginx (método real)
Primero restaurá el estado normal después del método A:
aws route53-recovery-cluster update-routing-control-states \
--update-routing-control-state-entries \
"[{\"RoutingControlArn\":\"$PRIMARY_RC_ARN\",\"RoutingControlState\":\"On\"},
{\"RoutingControlArn\":\"$SECONDARY_RC_ARN\",\"RoutingControlState\":\"Off\"}]" \
--endpoint-url $CLUSTER_ENDPOINT --region $AWS_REGION
aws cloudwatch set-alarm-state \
--alarm-name $ALARM_NAME \
--state-value OK \
--state-reason "Estado restaurado" --region $AWS_REGION
echo "✅ Estado normal restaurado"Ahora detené nginx via SSM:
COMMAND_ID=$(aws ssm send-command \
--instance-ids $EC2_ID \
--document-name AWS-RunShellScript \
--parameters 'commands=["systemctl stop nginx"]' \
--region $AWS_REGION \
--query 'Command.CommandId' --output text)
echo "Comando SSM: $COMMAND_ID"
echo "Monitoreando Health Check (puede tardar ~2-3 min)..."
echo ""
for i in $(seq 1 20); do
PRIMARY_STATE=$(aws route53-recovery-cluster get-routing-control-state \
--routing-control-arn $PRIMARY_RC_ARN \
--endpoint-url $CLUSTER_ENDPOINT --region $AWS_REGION \
--query 'RoutingControlState' --output text 2>/dev/null)
HTTP=$(curl -s -o /dev/null -w "%{http_code}" \
--connect-timeout 3 --max-time 5 http://$PRIMARY_ALB_DNS/ 2>/dev/null)
echo "[$(date '+%H:%M:%S')] ALB: HTTP$HTTP | Primary RC: $PRIMARY_STATE"
if [ "$PRIMARY_STATE" = "Off" ]; then
echo ""; echo "🎉 FAILOVER detectado automáticamente"
break
fi
sleep 30
done✅ Verificación del Lab 5
echo "=== Verificación Lab 5 ==="
P=$(aws route53-recovery-cluster get-routing-control-state \
--routing-control-arn $PRIMARY_RC_ARN \
--endpoint-url $CLUSTER_ENDPOINT --region $AWS_REGION \
--query 'RoutingControlState' --output text 2>/dev/null)
S=$(aws route53-recovery-cluster get-routing-control-state \
--routing-control-arn $SECONDARY_RC_ARN \
--endpoint-url $CLUSTER_ENDPOINT --region $AWS_REGION \
--query 'RoutingControlState' --output text 2>/dev/null)
[ "$P" = "Off" ] && echo "✅ Primario: $P" || echo "⚠️ Primario: $P"
[ "$S" = "On" ] && echo "✅ Secundario: $S" || echo "⚠️ Secundario: $S"
echo "📬 Revisá tu email para la notificación SNS"Siguiente paso → Lab 6: Failback