Saltar al contenido principal

Pruebas y Validación End-to-End

Introducción​

Antes de declarar un despliegue "en producción", es esencial validar que todos los componentes funcionen correctamente en conjunto. Esta sección presenta una metodología de pruebas completa.

Metodología de Pruebas​

┌─────────────────────────────────────────────────────────────┐
│ PIRÁMIDE DE PRUEBAS DE INFRAESTRUCTURA │
├─────────────────────────────────────────────────────────────┤
│ │
│ ▲ │
│ ╱ ╲ │
│ ╱ ╲ │
│ ╱ E2E ╲ Pruebas End-to-End │
│ ╱───────╲ (usuario real) │
│ ╱ ╲ │
│ ╱Integración╲ Pruebas de Integración │
│ ╱─────────────╲ (componentes juntos) │
│ ╱ ╲ │
│ ╱ Componentes ╲ Pruebas Unitarias │
│ ╱───────────────────╲ (cada servicio) │
│ ╱ ╲ │
│ ╱ Infraestructura ╲ Validación Config │
│ ╱─────────────────────────╲(CloudFormation,etc) │
│ │
│ Comenzar desde abajo, subir progresivamente │
│ │
└─────────────────────────────────────────────────────────────┘

Pruebas de Validación de Infraestructura​

1. Validación VPC y Red​

# Test 1: VPC existe y está disponible
aws ec2 describe-vpcs --vpc-ids vpc-xxx \
--query 'Vpcs[0].State'
# Esperado: "available"

# Test 2: Todos los subnets creados
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-xxx" \
--query 'Subnets[*].[SubnetId,CidrBlock,AvailabilityZone]'
# Esperado: 6 subnets listados

# Test 3: Internet Gateway adjunto
aws ec2 describe-internet-gateways \
--filters "Name=attachment.vpc-id,Values=vpc-xxx" \
--query 'InternetGateways[0].Attachments[0].State'
# Esperado: "available"

# Test 4: Rutas correctas
aws ec2 describe-route-tables \
--filters "Name=vpc-id,Values=vpc-xxx" \
--query 'RouteTables[*].Routes'
# Esperado: ruta 0.0.0.0/0 hacia igw para subnets públicos

2. Validación de Security Groups​

# Test 5: SG ALB permite HTTPS
aws ec2 describe-security-groups --group-ids sg-alb \
--query 'SecurityGroups[0].IpPermissions[?ToPort==`443`]'
# Esperado: regla con 0.0.0.0/0

# Test 6: SG App permite solo desde ALB
aws ec2 describe-security-groups --group-ids sg-app \
--query 'SecurityGroups[0].IpPermissions[*].UserIdGroupPairs[*].GroupId'
# Esperado: contiene sg-alb

# Test 7: SG DB permite solo desde App
aws ec2 describe-security-groups --group-ids sg-db \
--query 'SecurityGroups[0].IpPermissions[*].UserIdGroupPairs[*].GroupId'
# Esperado: contiene sg-app

3. Validación de Instancias EC2​

# Test 8: Instancias en ejecución
aws ec2 describe-instance-status \
--instance-ids i-app1 i-app2 \
--query 'InstanceStatuses[*].[InstanceId,InstanceState.Name,SystemStatus.Status,InstanceStatus.Status]'
# Esperado: todos "running", "ok", "ok"

# Test 9: Instancias en los subnets correctos
aws ec2 describe-instances --instance-ids i-app1 i-app2 \
--query 'Reservations[*].Instances[*].[InstanceId,SubnetId]'
# Esperado: subnets privados (10.0.11.0/24, 10.0.12.0/24)

Pruebas de Conectividad​

Matriz de Pruebas​

┌─────────────────────────────────────────────────────────────┐
│ MATRIZ DE CONECTIVIDAD │
├─────────────────────────────────────────────────────────────┤
│ │
│ DE / HACIA │ Internet │ ALB │ App │ DB │ S3 │
│ ────────────┼──────────┼─────┼─────┼─────┼─────────── │
│ Internet │ - │ ✅ │ ❌ │ ❌ │ ✅(public) │
│ ALB │ ✅ │ - │ ✅ │ ❌ │ ❌ │
│ App │ ✅(NAT) │ ❌ │ ✅ │ ✅ │ ✅(endpoint) │
│ DB │ ❌ │ ❌ │ ❌ │ - │ ❌ │
│ │
│ ✅ = Debe funcionar │
│ ❌ = Debe estar bloqueado │
│ │
└─────────────────────────────────────────────────────────────┘

Scripts de Prueba de Conectividad​

#!/bin/bash
# test-connectivity.sh

echo "=== Pruebas de Conectividad BlogPro ==="

# Test Internet → ALB (HTTPS)
echo -n "Test 1: Internet → ALB (HTTPS)... "
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://blog.example.com)
if [ "$HTTP_CODE" = "200" ]; then
echo "✅ PASS ($HTTP_CODE)"
else
echo "❌ FAIL ($HTTP_CODE)"
fi

# Test Internet → ALB (HTTP redirect)
echo -n "Test 2: HTTP → HTTPS redirect... "
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://blog.example.com)
if [ "$HTTP_CODE" = "301" ] || [ "$HTTP_CODE" = "302" ]; then
echo "✅ PASS (redirect $HTTP_CODE)"
else
echo "❌ FAIL ($HTTP_CODE)"
fi

# Test Health Check endpoint
echo -n "Test 3: Health Check... "
HEALTH=$(curl -s https://blog.example.com/health | jq -r '.status')
if [ "$HEALTH" = "healthy" ]; then
echo "✅ PASS"
else
echo "❌ FAIL ($HEALTH)"
fi

# Test Direct IP access (should fail - no public IP)
echo -n "Test 4: Direct IP access (should timeout)... "
timeout 5 curl -s http://10.0.11.20 > /dev/null 2>&1
if [ $? -eq 124 ]; then
echo "✅ PASS (correctly blocked)"
else
echo "❌ FAIL (should not be accessible)"
fi

echo "=== Pruebas finalizadas ==="

Pruebas de Load Balancing​

Verificar la Distribución​

#!/bin/bash
# test-load-balancing.sh

echo "=== Prueba de Distribución Load Balancer ==="

# Realizar 20 solicitudes y contar las respuestas de cada servidor
declare -A SERVER_COUNT

for i in {1..20}; do
SERVER=$(curl -s https://blog.example.com/api/server-id)
((SERVER_COUNT[$SERVER]++))
done

echo "Distribución de las solicitudes:"
for server in "${!SERVER_COUNT[@]}"; do
echo " $server: ${SERVER_COUNT[$server]} solicitudes"
done

# Verificar que ambos servidores recibieron solicitudes
if [ ${#SERVER_COUNT[@]} -ge 2 ]; then
echo "✅ Load balancing funcional"
else
echo "❌ Load balancing defectuoso"
fi

Prueba de Failover​

┌─────────────────────────────────────────────────────────────┐
│ PROCEDIMIENTO PRUEBA FAILOVER │
├─────────────────────────────────────────────────────────────┤
│ │
│ Paso 1 : Verificar estado inicial │
│ ──────────────────────────────── │
│ $ aws elbv2 describe-target-health \ │
│ --target-group-arn arn:aws:...:tg-app │
│ → Los 2 targets deben estar "healthy" │
│ │
│ Paso 2 : Simular falla de un servidor │
│ ───────────────────────────────────── │
│ $ aws ec2 stop-instances --instance-ids i-app1 │
│ │
│ Paso 3 : Esperar el health check (30-60s) │
│ ────────────────────────────────────────── │
│ $ watch -n 5 'curl -s https://blog.example.com/health' │
│ → El sitio debe permanecer accesible │
│ │
│ Paso 4 : Verificar que el tráfico va a App2 │
│ ──────────────────────────────────────────── │
│ $ for i in {1..10}; do curl -s https://blog.example.com/ │
│ api/server-id; done │
│ → Todas las respuestas provienen de App2 │
│ │
│ Paso 5 : Restaurar App1 │
│ ──────────────────────────── │
│ $ aws ec2 start-instances --instance-ids i-app1 │
│ → Después de unos minutos, tráfico distribuido nuevamente │
│ │
└─────────────────────────────────────────────────────────────┘

Pruebas de Rendimiento​

Prueba de Carga Básica​

# Usar Apache Benchmark (ab)
# 1000 solicitudes, 50 concurrentes
ab -n 1000 -c 50 https://blog.example.com/

# Resultados esperados:
# - Requests per second > 100
# - Time per request < 500ms (mean)
# - Failed requests: 0

Métricas a Monitorear​

MétricaUmbral AceptableAcción si se Supera
Latencia P50< 200msOptimizar código/cache
Latencia P95< 500msVerificar consultas DB
Latencia P99< 1000msInvestigar outliers
Error rate< 0.1%Verificar logs
CPU (EC2)< 70%Agregar instancias
Memoria (EC2)< 80%Aumentar tamaño

Pruebas de Seguridad​

Checklist de Seguridad​

┌─────────────────────────────────────────────────────────────┐
│ CHECKLIST DE SEGURIDAD │
├─────────────────────────────────────────────────────────────┤
│ │
│ RED │
│ ☐ Ningún puerto innecesario abierto a Internet │
│ ☐ SSH accesible solo vía bastion/VPN │
│ ☐ Base de datos no accesible desde Internet │
│ ☐ HTTPS forzado (redirect HTTP→HTTPS) │
│ │
│ CERTIFICADO SSL │
│ ☐ Certificado válido (no expirado) │
│ ☐ Cadena de certificados completa │
│ ☐ Solo TLS 1.2+ │
│ ☐ Sin vulnerabilidades SSL (prueba SSL Labs) │
│ │
│ INSTANCIAS │
│ ☐ Sin credenciales en el código/user-data │
│ ☐ Uso de roles IAM (sin claves) │
│ ☐ OS actualizado │
│ ☐ Firewall local configurado │
│ │
│ BASE DE DATOS │
│ ☐ Encryption at rest activado │
│ ☐ Encryption in transit (SSL) │
│ ☐ Sin credenciales por defecto │
│ ☐ Backups automáticos activados │
│ │
└─────────────────────────────────────────────────────────────┘

Prueba SSL con SSL Labs​

# Usar la prueba en línea SSL Labs
# https://www.ssllabs.com/ssltest/

# O con testssl.sh
docker run --rm -ti drwetter/testssl.sh https://blog.example.com

# Puntuación esperada: A o A+

Informe de Validación​

Plantilla de Informe​

# Informe de Validación - BlogPro

## Resumen Ejecutivo
- Fecha: YYYY-MM-DD
- Versión: 1.0
- Estado: ✅ VALIDADO / ❌ NO VALIDADO

## Pruebas de Infraestructura
| Prueba | Resultado | Notas |
|--------|-----------|-------|
| VPC creada | ✅ | vpc-xxx |
| Subnets (6) | ✅ | |
| IGW adjunto | ✅ | |
| Rutas correctas | ✅ | |

## Pruebas de Seguridad
| Prueba | Resultado | Notas |
|--------|-----------|-------|
| SG ALB | ✅ | Solo HTTPS |
| SG App | ✅ | Solo ALB |
| SG DB | ✅ | Solo App |
| SSL Grade | A | SSL Labs |

## Pruebas Funcionales
| Prueba | Resultado | Notas |
|--------|-----------|-------|
| Sitio accesible | ✅ | 200 OK |
| Health check | ✅ | healthy |
| Load balancing | ✅ | 50/50 |
| Failover | ✅ | < 60s |

## Pruebas de Rendimiento
| Métrica | Valor | Umbral | Estado |
|---------|-------|--------|--------|
| Latencia P50 | 150ms | < 200ms | ✅ |
| Latencia P95 | 380ms | < 500ms | ✅ |
| Throughput | 250 rps | > 100 rps | ✅ |

## Problemas Identificados
1. Ninguno

## Recomendaciones
1. Activar los VPC Flow Logs para monitoreo
2. Configurar alertas CloudWatch

## Aprobación
- [ ] Tech Lead
- [ ] Security Review
- [ ] Ops Team

Automatización de Pruebas​

Script de Validación Completo​

#!/bin/bash
# validate-deployment.sh

RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

DOMAIN="blog.example.com"
PASS=0
FAIL=0

function test_result() {
if [ $1 -eq 0 ]; then
echo -e "${GREEN}✅ PASS${NC}: $2"
((PASS++))
else
echo -e "${RED}❌ FAIL${NC}: $2"
((FAIL++))
fi
}

echo "========================================"
echo " VALIDACIÓN DESPLIEGUE BLOGPRO"
echo "========================================"
echo ""

# Test 1: Sitio accesible
echo "Test 1: Accesibilidad HTTPS"
curl -sf "https://${DOMAIN}" > /dev/null
test_result $? "Sitio accesible vía HTTPS"

# Test 2: Health check
echo "Test 2: Health Check"
HEALTH=$(curl -sf "https://${DOMAIN}/health" | jq -r '.status' 2>/dev/null)
[ "$HEALTH" = "healthy" ]
test_result $? "Health check endpoint"

# Test 3: HTTP redirect
echo "Test 3: HTTP → HTTPS redirect"
CODE=$(curl -sf -o /dev/null -w "%{http_code}" "http://${DOMAIN}")
[ "$CODE" = "301" ] || [ "$CODE" = "302" ]
test_result $? "HTTP redirect to HTTPS"

# Test 4: Certificado SSL
echo "Test 4: Certificado SSL válido"
curl -sf --cert-status "https://${DOMAIN}" > /dev/null
test_result $? "Certificado SSL válido"

# Test 5: Tiempo de respuesta
echo "Test 5: Tiempo de respuesta < 500ms"
TIME=$(curl -sf -o /dev/null -w "%{time_total}" "https://${DOMAIN}")
[ $(echo "$TIME < 0.5" | bc) -eq 1 ]
test_result $? "Tiempo de respuesta (${TIME}s)"

echo ""
echo "========================================"
echo " RESULTADO: $PASS PASS, $FAIL FAIL"
echo "========================================"

if [ $FAIL -gt 0 ]; then
exit 1
fi

Resumen​

FasePruebasHerramientas
InfraestructuraVPC, SG, RutasAWS CLI
ConectividadMatriz de accesocurl, nc, telnet
FuncionalE2E, Healthcurl, scripts
RendimientoCarga, latenciaab, hey, k6
SeguridadSSL, accesotestssl, nmap

Volver: Resumen MÓDULO 7