Tests et Validation End-to-End
Introduction
Avant de déclarer un déploiement "en production", il est essentiel de valider que tous les composants fonctionnent correctement ensemble. Cette section présente une méthodologie de test complète.
Méthodologie de Test
┌─────────────────────────────────────────────────────────────┐
│ PYRAMIDE DE TESTS INFRASTRUCTURE │
├─────────────────────────────────────────────────────────────┤
│ │
│ ▲ │
│ ╱ ╲ │
│ ╱ ╲ │
│ ╱ E2E ╲ Tests End-to-End │
│ ╱───────╲ (utilisateur réel) │
│ ╱ ╲ │
│ ╱Integration╲ Tests d'Intégration │
│ ╱─────────────╲ (composants ensemble) │
│ ╱ ╲ │
│ ╱ Composants ╲ Tests Unitaires │
│ ╱───────────────────╲ (chaque service) │
│ ╱ ╲ │
│ ╱ Infrastructure ╲ Validation Config │
│ ╱─────────────────────────╲(CloudFormation,etc) │
│ │
│ Commencer par le bas, remonter progressivement │
│ │
└─────────────────────────────────────────────────────────────┘
Tests de Validation Infrastructure
1. Validation VPC et Réseau
# Test 1: VPC existe et est disponible
aws ec2 describe-vpcs --vpc-ids vpc-xxx \
--query 'Vpcs[0].State'
# Attendu: "available"
# Test 2: Tous les subnets créés
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-xxx" \
--query 'Subnets[*].[SubnetId,CidrBlock,AvailabilityZone]'
# Attendu: 6 subnets listés
# Test 3: Internet Gateway attaché
aws ec2 describe-internet-gateways \
--filters "Name=attachment.vpc-id,Values=vpc-xxx" \
--query 'InternetGateways[0].Attachments[0].State'
# Attendu: "available"
# Test 4: Routes correctes
aws ec2 describe-route-tables \
--filters "Name=vpc-id,Values=vpc-xxx" \
--query 'RouteTables[*].Routes'
# Attendu: route 0.0.0.0/0 vers igw pour subnets publics
2. Validation Security Groups
# Test 5: SG ALB autorise HTTPS
aws ec2 describe-security-groups --group-ids sg-alb \
--query 'SecurityGroups[0].IpPermissions[?ToPort==`443`]'
# Attendu: règle avec 0.0.0.0/0
# Test 6: SG App autorise depuis ALB uniquement
aws ec2 describe-security-groups --group-ids sg-app \
--query 'SecurityGroups[0].IpPermissions[*].UserIdGroupPairs[*].GroupId'
# Attendu: contient sg-alb
# Test 7: SG DB autorise depuis App uniquement
aws ec2 describe-security-groups --group-ids sg-db \
--query 'SecurityGroups[0].IpPermissions[*].UserIdGroupPairs[*].GroupId'
# Attendu: contient sg-app
3. Validation Instances EC2
# Test 8: Instances running
aws ec2 describe-instance-status \
--instance-ids i-app1 i-app2 \
--query 'InstanceStatuses[*].[InstanceId,InstanceState.Name,SystemStatus.Status,InstanceStatus.Status]'
# Attendu: tous "running", "ok", "ok"
# Test 9: Instances dans les bons subnets
aws ec2 describe-instances --instance-ids i-app1 i-app2 \
--query 'Reservations[*].Instances[*].[InstanceId,SubnetId]'
# Attendu: subnets privés (10.0.11.0/24, 10.0.12.0/24)
Tests de Connectivité
Matrice de Tests
┌─────────────────────────────────────────────────────────────┐
│ MATRICE DE CONNECTIVITÉ │
├─────────────────────────────────────────────────────────────┤
│ │
│ DE / VERS │ Internet │ ALB │ App │ DB │ S3 │
│ ─────────────┼──────────┼─────┼─────┼─────┼─────────── │
│ Internet │ - │ ✅ │ ❌ │ ❌ │ ✅(public) │
│ ALB │ ✅ │ - │ ✅ │ ❌ │ ❌ │
│ App │ ✅(NAT) │ ❌ │ ✅ │ ✅ │ ✅(endpoint) │
│ DB │ ❌ │ ❌ │ ❌ │ - │ ❌ │
│ │
│ ✅ = Doit fonctionner │
│ ❌ = Doit être bloqué │
│ │
└─────────────────────────────────────────────────────────────┘
Scripts de Test de Connectivité
#!/bin/bash
# test-connectivity.sh
echo "=== Tests de Connectivité 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 "=== Tests terminés ==="
Tests de Load Balancing
Vérifier la Distribution
#!/bin/bash
# test-load-balancing.sh
echo "=== Test Distribution Load Balancer ==="
# Faire 20 requêtes et compter les réponses de chaque serveur
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 "Distribution des requêtes:"
for server in "${!SERVER_COUNT[@]}"; do
echo " $server: ${SERVER_COUNT[$server]} requêtes"
done
# Vérifier que les deux serveurs ont reçu des requêtes
if [ ${#SERVER_COUNT[@]} -ge 2 ]; then
echo "✅ Load balancing fonctionnel"
else
echo "❌ Load balancing défaillant"
fi
Test de Failover
┌─────────────────────────────────────────────────────────────┐
│ PROCÉDURE TEST FAILOVER │
├─────────────────────────────────────────────────────────────┤
│ │
│ Étape 1 : Vérifier état initial │
│ ──────────────────────────────── │
│ $ aws elbv2 describe-target-health \ │
│ --target-group-arn arn:aws:...:tg-app │
│ → Les 2 targets doivent être "healthy" │
│ │
│ Étape 2 : Simuler panne d'un serveur │
│ ───────────────────────────────────── │
│ $ aws ec2 stop-instances --instance-ids i-app1 │
│ │
│ Étape 3 : Attendre le health check (30-60s) │
│ ────────────────────────────────────────── │
│ $ watch -n 5 'curl -s https://blog.example.com/health' │
│ → Le site doit rester accessible │
│ │
│ Étape 4 : Vérifier que le trafic va sur App2 │
│ ──────────────────────────────────────────── │
│ $ for i in {1..10}; do curl -s https://blog.example.com/ │
│ api/server-id; done │
│ → Toutes les réponses viennent de App2 │
│ │
│ Étape 5 : Restaurer App1 │
│ ──────────────────────────── │
│ $ aws ec2 start-instances --instance-ids i-app1 │
│ → Après quelques minutes, trafic distribué à nouveau │
│ │
└─────────────────────────────────────────────────────────────┘
Tests de Performance
Test de Charge Basique
# Utiliser Apache Benchmark (ab)
# 1000 requêtes, 50 concurrentes
ab -n 1000 -c 50 https://blog.example.com/
# Résultats attendus:
# - Requests per second > 100
# - Time per request < 500ms (mean)
# - Failed requests: 0
Métriques à Surveiller
| Métrique | Seuil Acceptable | Action si Dépassé |
|---|---|---|
| Latence P50 | < 200ms | Optimiser code/cache |
| Latence P95 | < 500ms | Vérifier DB queries |
| Latence P99 | < 1000ms | Investiguer outliers |
| Error rate | < 0.1% | Vérifier logs |
| CPU (EC2) | < 70% | Ajouter instances |
| Memory (EC2) | < 80% | Augmenter taille |
Tests de Sécurité
Checklist Sécurité
┌─────────────────────────────────────────────────────────────┐
│ CHECKLIST SÉCURITÉ │
├─────────────────────────────────────────────────────────────┤
│ │
│ RÉSEAU │
│ ☐ Aucun port inutile ouvert sur Internet │
│ ☐ SSH accessible uniquement via bastion/VPN │
│ ☐ Database non accessible depuis Internet │
│ ☐ HTTPS enforced (redirect HTTP→HTTPS) │
│ │
│ CERTIFICAT SSL │
│ ☐ Certificat valide (pas expiré) │
│ ☐ Chaîne de certificats complète │
│ ☐ TLS 1.2+ uniquement │
│ ☐ Pas de vulnérabilités SSL (test SSL Labs) │
│ │
│ INSTANCES │
│ ☐ Pas de credentials dans le code/user-data │
│ ☐ IAM roles utilisés (pas de clés) │
│ ☐ OS à jour │
│ ☐ Firewall local configuré │
│ │
│ BASE DE DONNÉES │
│ ☐ Encryption at rest activé │
│ ☐ Encryption in transit (SSL) │
│ ☐ Pas de credentials par défaut │
│ ☐ Backups automatiques activés │
│ │
└─────────────────────────────────────────────────────────────┘
Test SSL avec SSL Labs
# Utiliser le test en ligne SSL Labs
# https://www.ssllabs.com/ssltest/
# Ou avec testssl.sh
docker run --rm -ti drwetter/testssl.sh https://blog.example.com
# Score attendu: A ou A+
Rapport de Validation
Template de Rapport
# Rapport de Validation - BlogPro
## Résumé Exécutif
- Date: YYYY-MM-DD
- Version: 1.0
- Statut: ✅ VALIDÉ / ❌ NON VALIDÉ
## Tests Infrastructure
| Test | Résultat | Notes |
|------|----------|-------|
| VPC créé | ✅ | vpc-xxx |
| Subnets (6) | ✅ | |
| IGW attaché | ✅ | |
| Routes correctes | ✅ | |
## Tests Sécurité
| Test | Résultat | Notes |
|------|----------|-------|
| SG ALB | ✅ | HTTPS only |
| SG App | ✅ | ALB only |
| SG DB | ✅ | App only |
| SSL Grade | A | SSL Labs |
## Tests Fonctionnels
| Test | Résultat | Notes |
|------|----------|-------|
| Site accessible | ✅ | 200 OK |
| Health check | ✅ | healthy |
| Load balancing | ✅ | 50/50 |
| Failover | ✅ | < 60s |
## Tests Performance
| Métrique | Valeur | Seuil | Statut |
|----------|--------|-------|--------|
| Latence P50 | 150ms | < 200ms | ✅ |
| Latence P95 | 380ms | < 500ms | ✅ |
| Throughput | 250 rps | > 100 rps | ✅ |
## Problèmes Identifiés
1. Aucun
## Recommandations
1. Activer les VPC Flow Logs pour monitoring
2. Configurer des alertes CloudWatch
## Approbation
- [ ] Tech Lead
- [ ] Security Review
- [ ] Ops Team
Automatisation des Tests
Script de Validation Complet
#!/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 " VALIDATION DÉPLOIEMENT BLOGPRO"
echo "========================================"
echo ""
# Test 1: Site accessible
echo "Test 1: Accessibilité HTTPS"
curl -sf "https://${DOMAIN}" > /dev/null
test_result $? "Site accessible via 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: SSL Certificate
echo "Test 4: Certificat SSL valide"
curl -sf --cert-status "https://${DOMAIN}" > /dev/null
test_result $? "Certificat SSL valide"
# Test 5: Response time
echo "Test 5: Temps de réponse < 500ms"
TIME=$(curl -sf -o /dev/null -w "%{time_total}" "https://${DOMAIN}")
[ $(echo "$TIME < 0.5" | bc) -eq 1 ]
test_result $? "Temps de réponse (${TIME}s)"
echo ""
echo "========================================"
echo " RÉSULTAT: $PASS PASS, $FAIL FAIL"
echo "========================================"
if [ $FAIL -gt 0 ]; then
exit 1
fi
Résumé
| Phase | Tests | Outils |
|---|---|---|
| Infrastructure | VPC, SG, Routes | AWS CLI |
| Connectivité | Matrice accès | curl, nc, telnet |
| Fonctionnel | E2E, Health | curl, scripts |
| Performance | Charge, latence | ab, hey, k6 |
| Sécurité | SSL, accès | testssl, nmap |
Retour : Vue d'ensemble MODULE 7