---

---

# [JAUNE] EXERCICE 6 : ELB + AUTO SCALING - HAUTE DISPONIBILITÉ

## [LISTE] ÉNONCÉ

### Contexte professionnel

Tu es ingénieur DevOps dans une entreprise e-commerce. Le Black Friday approche et le trafic va **exploser** :
- Trafic normal : 1,000 utilisateurs/heure
- Black Friday : 50,000 utilisateurs/heure (x50 !)

**Problème actuel :**
- 1 seul serveur EC2 t2.micro
- Si le serveur tombe en panne -> Site inaccessible
- Si trafic élevé -> Serveur surchargé, site lent/inaccessible
- Pas de scalabilité

**Mission :** Mettre en place une infrastructure **hautement disponible** et **auto-scalable** qui :
- Répartit le trafic sur plusieurs serveurs (Load Balancing)
- Ajoute/retire automatiquement des serveurs selon la charge (Auto Scaling)
- Survit à la panne d'une Availability Zone complète
- Maintient les performances même en cas de pic de trafic

### Architecture cible : HA Auto-Scaling

```
                        Internet
                           v
                  Route 53 (DNS)
                           v
                ┌──────────────────────┐
                │ Application Load     │
                │ Balancer (ALB)       │
                │ - Multi-AZ           │
                │ - Health Checks      │
                │ - SSL/TLS            │
                └──────────────────────┘
                     v           v
        ┌────────────────────────────────┐
        │   Auto Scaling Group (ASG)     │
        │   - Min: 2 instances           │
        │   - Max: 10 instances          │
        │   - Desired: 2 instances       │
        └────────────────────────────────┘
                v                v
    ┌─────────────────┐  ┌─────────────────┐
    │ AZ us-east-1a   │  │ AZ us-east-1b   │
    │                 │  │                 │
    │ EC2 Instance 1  │  │ EC2 Instance 2  │
    │ - t3.micro      │  │ - t3.micro      │
    │ - Apache + PHP  │  │ - Apache + PHP  │
    │ - Monitoring    │  │ - Monitoring    │
    └─────────────────┘  └─────────────────┘
                v                v
            ┌─────────────────────────┐
            │   RDS Multi-AZ          │
            │   MySQL (Primary + Std) │
            └─────────────────────────┘
```

### Cahier des charges

**Load Balancer (ALB) :**
- Répartition du trafic entre instances
- Health checks toutes les 30 secondes
- Multi-AZ (us-east-1a, us-east-1b)
- HTTPS avec certificat SSL (optionnel)
- Sticky sessions (optionnel)

**Auto Scaling Group (ASG) :**
- Minimum : 2 instances (redondance)
- Maximum : 10 instances (limite de coût)
- Desired capacity : 2 instances (normal)
- Scaling policies :
  - Scale Out : CPU > 70% -> +1 instance
  - Scale In : CPU < 30% -> -1 instance
- Multi-AZ deployment

**Application web :**
- Page dynamique PHP affichant le hostname
- Script de stress test pour tester l'auto-scaling
- Logs d'accès pour monitoring

### Contraintes techniques

- VPC : multi-tier-vpc (Exercice 4) ou nouveau
- Instances : t3.micro (Free Tier eligible)
- AMI : Ubuntu 22.04 LTS avec Apache + PHP
- RDS : Optionnel (peut utiliser DynamoDB ou SQLite)
- Durée estimée : 4-5 heures

---

## [OBJECTIF] OBJECTIFS PÉDAGOGIQUES

À la fin de cet exercice, tu sauras :

- [OK] Comprendre la haute disponibilité (HA) et la scalabilité
- [OK] Différencier ALB, NLB et CLB
- [OK] Créer un Application Load Balancer
- [OK] Configurer des Target Groups
- [OK] Mettre en place des Health Checks
- [OK] Créer un Launch Template
- [OK] Configurer un Auto Scaling Group
- [OK] Définir des Scaling Policies
- [OK] Tester l'auto-scaling avec charge
- [OK] Simuler une panne d'AZ
- [OK] Monitorer avec CloudWatch
- [OK] Calculer les coûts HA
- [OK] Optimiser les performances

---

## [DOCS] PRÉREQUIS

- Exercices 1 à 5 terminés
- VPC avec subnets publics dans 2 AZ (Exercice 4)
- Notions de réseaux et HTTP
- Compréhension des concepts de scalabilité

---

## [OK] SOLUTION COMPLÈTE

### ÉTAPE 1 : Comprendre la Haute Disponibilité et le Load Balancing

#### Qu'est-ce que la Haute Disponibilité (HA) ?

**Haute Disponibilité (High Availability, HA)** = Capacité d'un système à rester opérationnel le plus longtemps possible

**Mesure : Pourcentage de disponibilité (uptime)**

| Disponibilité | Downtime annuel | Downtime mensuel | Cas d'usage |
|---------------|-----------------|------------------|-------------|
| 90% (1 nine) | 36.5 jours | 3 jours | [X] Inacceptable |
| 99% (2 nines) | 3.65 jours | 7.2 heures | [ATTENTION] Applications internes |
| 99.9% (3 nines) | 8.76 heures | 43.2 minutes | [OK] Production standard |
| 99.99% (4 nines) | 52.6 minutes | 4.32 minutes | * Mission-critical |
| 99.999% (5 nines) | 5.26 minutes | 26 secondes | [GEM_STONE] Banques, santé |

**Objectif typique en production : 99.9% (3 nines)**

---

**Comment atteindre la HA ?**

**1. Éliminer les Single Points of Failure (SPOF)**

**SPOF** = Point unique de défaillance = Si ça tombe, tout tombe

**Exemple de SPOF :**

```
Internet -> 1 seul serveur EC2 -> Base de données
          ^ SPOF !
```

Si ce serveur tombe en panne (hardware failure, bug, etc.), **site inaccessible**.

---

**Solution : Redondance**

```
Internet -> Load Balancer
              v       v
          Serveur 1  Serveur 2  (Redondance)
              v       v
          Base de données Multi-AZ
```

Si Serveur 1 tombe, le Load Balancer redirige vers Serveur 2.

---

**2. Distribution Multi-AZ**

**Availability Zone (AZ)** = Data center isolé

**Risque :** Une AZ entière peut tomber (incendie, inondation, panne électrique)

**Solution :** Déployer dans plusieurs AZ

```
AZ us-east-1a              AZ us-east-1b
   Serveur 1                  Serveur 2
   Database Primary           Database Standby
```

Si toute l'AZ us-east-1a tombe, us-east-1b continue de fonctionner.

---

**3. Health Checks (Surveillance de santé)**

**Health Check** = Vérification régulière que les serveurs sont en bonne santé

**Exemple :**

Load Balancer ping `/health` toutes les 30 secondes sur chaque serveur.

**Si HTTP 200 OK -> Serveur sain**

**Si timeout/erreur -> Serveur malsain -> Retirer du pool**

---

**4. Auto-healing (Auto-réparation)**

Si une instance tombe en panne, Auto Scaling Group la détecte et **lance automatiquement une nouvelle instance** pour la remplacer.

**Guérison automatique ! ***

---

#### Qu'est-ce que le Load Balancing ?

**Load Balancer (LB)** = Équilibreur de charge = Répartit le trafic entre plusieurs serveurs

**Analogie :**

Un Load Balancer = Hôtesse d'accueil dans un restaurant

- Des clients arrivent (requêtes HTTP)
- L'hôtesse regarde quelles tables sont disponibles (serveurs sains)
- Elle dirige chaque client vers une table libre
- Si une table est pleine (serveur surchargé), elle choisit une autre table

**Résultat : Charge répartie équitablement**

---

**Avantages du Load Balancing :**

**1. Haute disponibilité**

Si un serveur tombe, le LB redirige automatiquement vers les autres.

**2. Scalabilité**

Ajouter des serveurs -> Plus de capacité (sans changer l'application)

**3. Performance**

Chaque serveur traite moins de requêtes -> Réponses plus rapides

**4. Maintenance sans downtime**

Retirer un serveur du pool -> Faire la maintenance -> Le remettre

Pendant ce temps, les autres serveurs prennent le relais.

---

#### Types de Load Balancers AWS

**AWS propose 4 types de Load Balancers :**

| Type | Couche OSI | Protocoles | Cas d'usage | Coût |
|------|-----------|------------|-------------|------|
| **ALB** (Application LB) | Layer 7 (HTTP/HTTPS) | HTTP, HTTPS, WebSocket | * Applications web, APIs REST | $0.0225/h + $0.008/LCU |
| **NLB** (Network LB) | Layer 4 (TCP/UDP) | TCP, UDP, TLS | Performance extrême, gaming | $0.0225/h + $0.006/LCU |
| **GLB** (Gateway LB) | Layer 3 (IP) | IP | Firewalls virtuels, IPS/IDS | $0.0125/h + $0.004/LCU |
| **CLB** (Classic LB) | Layer 4 & 7 | HTTP, HTTPS, TCP, SSL | [ATTENTION] Legacy (déprécié) | $0.025/h + $0.008/GB |

**LCU** = Load Balancer Capacity Unit (métrique de charge)

---

**Application Load Balancer (ALB) - Détails**

**Niveau :** Layer 7 (Application)

**Comprend HTTP/HTTPS :**

Peut lire le contenu des requêtes HTTP :
- URL path : /api/users, /static/images
- Host header : api.example.com, www.example.com
- Headers : User-Agent, Accept-Language
- Query strings : ?page=2&sort=date

**Fonctionnalités avancées :**

**1. Path-based routing**

```
/api/* -> Target Group API
/static/* -> Target Group Static (S3)
/admin/* -> Target Group Admin
```

**2. Host-based routing**

```
api.example.com -> Target Group API
www.example.com -> Target Group Web
admin.example.com -> Target Group Admin
```

**3. WebSocket support**

Connexions persistantes pour chat, gaming, etc.

**4. HTTP/2 et gRPC**

Protocoles modernes

**5. SSL/TLS termination**

Le LB gère le HTTPS, les serveurs reçoivent du HTTP simple.

**6. Sticky sessions**

Un utilisateur est toujours redirigé vers le même serveur (pour sessions).

**7. Authentication**

Intégration Cognito, OIDC (login avant d'accéder à l'app).

---

**Network Load Balancer (NLB) - Détails**

**Niveau :** Layer 4 (Transport)

**Ne comprend PAS HTTP :**

Travaille au niveau TCP/UDP (ne lit pas le contenu).

**Avantages :**

**1. Performance extrême**

- Latence ultra-faible (< 100µs)
- Millions de requêtes/seconde
- Pas de traitement HTTP (moins de overhead)

**2. IP statique**

NLB peut avoir une Elastic IP statique.

**3. Preserve source IP**

Les serveurs voient l'IP réelle du client (pas l'IP du LB).

**4. Non-HTTP protocols**

TCP, UDP, TLS (pas limité à HTTP).

**Cas d'usage :**

- Gaming servers (UDP)
- IoT (MQTT, CoAP)
- Bases de données (MySQL, PostgreSQL)
- Applications legacy non-HTTP

---

**Gateway Load Balancer (GLB) - Détails**

**Niveau :** Layer 3 (Network)

**Cas d'usage :** Déployer des appliances virtuelles (firewalls, IDS/IPS)

**Flux :**

```
Internet -> GLB -> Firewall virtuel -> GLB -> Application
```

**Très spécialisé** (rarement utilisé)

---

**Classic Load Balancer (CLB) - Legacy**

**Ancienne génération** (avant ALB/NLB)

**AWS recommande de migrer vers ALB ou NLB.**

**Désavantages :**

- Moins de fonctionnalités
- Performances inférieures
- Support limité

**Ne pas utiliser pour nouveaux projets.**

---

**Comparaison ALB vs NLB :**

| Critère | ALB | NLB |
|---------|-----|-----|
| **Performance** | Bonne (1000-10k RPS) | Excellente (millions RPS) |
| **Latence** | ~10-50ms | <1ms |
| **Routage avancé** | [OK] Path, host, headers | [X] Seulement port |
| **WebSocket** | [OK] Oui | [OK] Oui |
| **HTTP/2** | [OK] Oui | [X] Non |
| **SSL termination** | [OK] Oui | [OK] Oui |
| **IP statique** | [X] DNS uniquement | [OK] Elastic IP |
| **Preserve client IP** | [X] Header X-Forwarded-For | [OK] Natif |
| **Coût** | Moyen | Légèrement moins cher |

**Recommandation :**

**ALB** : Applications web, APIs REST (99% des cas) *

**NLB** : Performance extrême, non-HTTP, IP statique nécessaire

**Pour cet exercice : ALB** (application web)

---

#### Qu'est-ce que l'Auto Scaling ?

**Auto Scaling** = Ajustement automatique du nombre de serveurs selon la charge

**Principe :**

```
Charge faible (nuit)        Charge normale            Charge élevée (Black Friday)
  1 instance                  2 instances                  10 instances
     v                           vv                          vvvvvvvvvv
   Scale In                                                  Scale Out
  (économie)                                              (performance)
```

---

**Avantages :**

**1. Réduction des coûts**

Pas besoin de payer pour 10 instances 24/7.

1 instance la nuit -> $8/mois

2 instances le jour -> $16/mois

10 instances pendant 2h (pic) -> $1

**Total : ~$25/mois au lieu de $80/mois (10 instances 24/7)**

**2. Performance garantie**

Même en cas de pic de trafic inattendu, des instances supplémentaires se lancent automatiquement.

**3. Résilience**

Si une instance tombe, ASG lance automatiquement une nouvelle instance.

---

**Composants Auto Scaling :**

**1. Launch Template (ou Launch Configuration)**

**Modèle** définissant comment créer une instance :
- AMI
- Instance type
- Security groups
- User data (script d'installation)
- Storage
- IAM role

**C'est le "blueprint" des instances.**

---

**2. Auto Scaling Group (ASG)**

**Groupe** qui gère les instances :

**Capacity :**
- **Minimum :** Nombre minimum d'instances (ex: 2)
- **Desired :** Nombre souhaité (ex: 2 normalement)
- **Maximum :** Limite max (ex: 10)

**Subnets :** Dans quelles AZ déployer

**Load Balancer :** Quel LB utiliser

**Health Checks :** ELB et/ou EC2

**Scaling Policies :** Quand et comment scaler

---

**3. Scaling Policies**

**Règles** définissant quand ajouter/retirer des instances.

**Types de policies :**

**a) Target Tracking Scaling**

"Maintenir CPU à 50%"

Si CPU > 50% -> Ajouter des instances

Si CPU < 50% -> Retirer des instances

**Le plus simple et recommandé ! ***

---

**b) Step Scaling**

Règles graduelles :

```
CPU 30-50% : Ne rien faire
CPU 50-70% : +1 instance
CPU 70-90% : +2 instances
CPU > 90%  : +3 instances
```

**Plus de contrôle**, mais plus complexe.

---

**c) Simple Scaling**

"Si CPU > 70%, ajouter 1 instance"

**Moins flexible**, cooldown fixe.

---

**d) Scheduled Scaling**

Scaler à des heures fixes :

```
Lundi-Vendredi 9h-18h : 5 instances
Nuit et weekend : 2 instances
```

**Idéal si charge prévisible.**

---

**Exemple de cycle Auto Scaling :**

```
1. Trafic augmente
   v
2. CPU monte à 75%
   v
3. CloudWatch Alarm déclenché
   v
4. Scaling Policy "Scale Out"
   v
5. ASG lance +1 instance (Launch Template)
   v
6. Instance démarre, installe app (User Data)
   v
7. Health Check réussit
   v
8. Load Balancer ajoute l'instance au pool
   v
9. Trafic réparti sur plus d'instances
   v
10. CPU redescend à 50%
```

**Complètement automatique ! ***

---

#### Métriques pour Auto Scaling

**CloudWatch collecte des métriques pour déclencher le scaling :**

| Métrique | Description | Seuil typique Scale Out | Seuil typique Scale In |
|----------|-------------|-------------------------|------------------------|
| **CPU Utilization** | % d'utilisation CPU | > 70% | < 30% |
| **Network In** | Trafic entrant (bytes) | > 10 MB/s | < 2 MB/s |
| **Network Out** | Trafic sortant | > 10 MB/s | < 2 MB/s |
| **Request Count** | Nombre de requêtes (ALB) | > 1000 req/min | < 200 req/min |
| **Target Response Time** | Latence des réponses | > 500ms | < 100ms |
| **Custom Metrics** | Métrique personnalisée | Variable | Variable |

**Recommandation : CPU Utilization** (le plus fiable)

---

### ÉTAPE 2 : Préparer l'AMI avec l'application web

**Pour que les instances lancées automatiquement soient fonctionnelles, on va créer une AMI personnalisée avec Apache + PHP préinstallé.**

---

#### Option 1 : Créer une AMI manuellement

**1. Lancer une instance EC2 temporaire**

EC2 -> Launch instances

**Name :** `web-server-template`

**AMI :** Ubuntu Server 22.04 LTS

**Instance type :** t3.micro

**Key pair :** (Ta clé existante)

**Network settings :**

**VPC :** multi-tier-vpc (ou default)

**Subnet :** public-subnet-1a

**Auto-assign public IP :** Enable

**Security group :** Créer nouveau

**Security group name :** `web-sg`

**Inbound rules :**

| Type | Port | Source | Description |
|------|------|--------|-------------|
| SSH | 22 | My IP | SSH access |
| HTTP | 80 | 0.0.0.0/0 | Web traffic |

**Launch instance**

---

**2. Se connecter à l'instance**

```bash
ssh -i "ma-cle.pem" ubuntu@<IP-PUBLIQUE>
```

---

**3. Installer Apache et PHP**

```bash
# Mettre à jour les packages
sudo apt update

# Installer Apache
sudo apt install -y apache2

# Installer PHP et modules
sudo apt install -y php libapache2-mod-php php-mysql

# Vérifier qu'Apache tourne
sudo systemctl status apache2
```

---

**4. Créer une page PHP dynamique**

```bash
sudo nano /var/www/html/index.php
```

**Contenu :**

```php
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Load Balancer Demo</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        .container {
            background: rgba(255,255,255,0.1);
            padding: 30px;
            border-radius: 10px;
            backdrop-filter: blur(10px);
        }
        .info-box {
            background: rgba(255,255,255,0.2);
            padding: 15px;
            margin: 10px 0;
            border-radius: 5px;
        }
        .hostname {
            font-size: 24px;
            font-weight: bold;
            color: #FFD700;
        }
        .timestamp {
            font-size: 14px;
            color: #E0E0E0;
        }
        h1 {
            text-align: center;
            margin-bottom: 30px;
        }
        .load-test {
            margin-top: 20px;
            padding: 15px;
            background: rgba(255,255,255,0.15);
            border-radius: 5px;
        }
        button {
            background: #4CAF50;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background: #45a049;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>[RAPIDE] Load Balancer Demo - Auto Scaling</h1>
        
        <div class="info-box">
            <strong>Serveur :</strong>
            <div class="hostname"><?php echo gethostname(); ?></div>
        </div>
        
        <div class="info-box">
            <strong>Adresse IP :</strong> <?php echo $_SERVER['SERVER_ADDR']; ?>
        </div>
        
        <div class="info-box">
            <strong>IP Client :</strong> <?php echo $_SERVER['REMOTE_ADDR']; ?>
        </div>
        
        <div class="info-box">
            <strong>Timestamp :</strong>
            <div class="timestamp"><?php echo date('Y-m-d H:i:s'); ?></div>
        </div>
        
        <div class="info-box">
            <strong>Charge système (Load Average) :</strong>
            <?php 
                $load = sys_getloadavg();
                echo sprintf("1 min: %.2f | 5 min: %.2f | 15 min: %.2f", 
                    $load[0], $load[1], $load[2]
                );
            ?>
        </div>
        
        <div class="info-box">
            <strong>Utilisation mémoire :</strong>
            <?php 
                $free = shell_exec('free -m');
                $free = (string)trim($free);
                $free_arr = explode("\n", $free);
                $mem = explode(" ", $free_arr[1]);
                $mem = array_filter($mem);
                $mem = array_merge($mem);
                $memory_usage = $mem[2] / $mem[1] * 100;
                echo sprintf("%.2f%% utilisé", $memory_usage);
            ?>
        </div>
        
        <div class="load-test">
            <h3>Test de charge CPU</h3>
            <p>Clique pour simuler une charge élevée (30 secondes)</p>
            <button onclick="loadTest()">[RAPIDE] Démarrer le test</button>
            <div id="status"></div>
        </div>
    </div>
    
    <script>
        function loadTest() {
            document.getElementById('status').innerHTML = 
                '<p>[HOURGLASS_WITH_FLOWING_SAND] Test en cours... Le serveur calcule des nombres premiers.</p>';
            
            fetch('stress.php')
                .then(response => response.text())
                .then(data => {
                    document.getElementById('status').innerHTML = 
                        '<p>[OK] Test terminé ! ' + data + '</p>';
                })
                .catch(error => {
                    document.getElementById('status').innerHTML = 
                        '<p>[X] Erreur: ' + error + '</p>';
                });
        }
        
        // Rafraîchir automatiquement toutes les 5 secondes
        setTimeout(() => location.reload(), 5000);
    </script>
</body>
</html>
```

**Enregistrer : Ctrl+O, Entrée, Ctrl+X**

---

**Explication du code :**

```php
<?php echo gethostname(); ?>
```

**Affiche le hostname de l'instance** (ex: ip-10-0-1-123)

**Permet de voir sur quel serveur on est** (crucial pour tester le load balancing).

---

```php
$load = sys_getloadavg();
```

**Récupère la charge système (Load Average)**

Valeurs typiques :
- < 1 : Charge faible
- 1-2 : Charge normale
- > 2 : Charge élevée (sur t3.micro avec 2 vCPUs)

---

```php
$free = shell_exec('free -m');
```

**Exécute la commande `free -m`** (affiche la mémoire)

Parse le résultat pour calculer le % d'utilisation.

---

```javascript
setTimeout(() => location.reload(), 5000);
```

**Rafraîchit la page toutes les 5 secondes**

Permet de voir en temps réel sur quel serveur on est redirigé par le LB.

---

**5. Créer le script de stress test**

```bash
sudo nano /var/www/html/stress.php
```

**Contenu :**

```php
<?php
// Script de stress test CPU
// Calcule des nombres premiers pendant 30 secondes

set_time_limit(60); // Limite à 60 secondes max

$start_time = time();
$duration = 30; // Durée du test en secondes
$count = 0;

// Fonction pour vérifier si un nombre est premier
function is_prime($num) {
    if ($num <= 1) return false;
    if ($num <= 3) return true;
    if ($num % 2 == 0 || $num % 3 == 0) return false;
    
    for ($i = 5; $i * $i <= $num; $i += 6) {
        if ($num % $i == 0 || $num % ($i + 2) == 0) {
            return false;
        }
    }
    return true;
}

// Calculer des nombres premiers pendant 30 secondes
$number = 2;
while (time() - $start_time < $duration) {
    if (is_prime($number)) {
        $count++;
    }
    $number++;
}

$elapsed = time() - $start_time;

echo sprintf(
    "Calculé %d nombres premiers en %d secondes. Dernier nombre testé: %d", 
    $count, 
    $elapsed, 
    $number
);
?>
```

**Enregistrer**

---

**6. Configurer Apache pour utiliser index.php par défaut**

```bash
# Supprimer index.html par défaut
sudo rm /var/www/html/index.html

# Redémarrer Apache
sudo systemctl restart apache2
```

---

**7. Tester l'application**

**Dans le navigateur :**

```
http://<IP-PUBLIQUE-INSTANCE>
```

**Tu devrais voir la page avec le hostname, IP, etc.**

**Tester le stress test :** Cliquer sur "Démarrer le test"

**Attendre 30 secondes -> Message de confirmation**

---

**8. Créer l'AMI**

**EC2 -> Instances -> Sélectionner `web-server-template`**

**Actions -> Image and templates -> Create image**

---

**Image name :** `web-server-ami-v1`

**Image description :** `Ubuntu 22.04 + Apache + PHP + Load Balancer Demo App`

**No reboot :** [x] Décocher (laisser coché pour éviter le reboot)

**[ATTENTION] En production, toujours décocher pour garantir la cohérence du filesystem**

---

**Create image**

**[HOURGLASS_WITH_FLOWING_SAND] Création de l'AMI... (2-5 minutes)**

**Images -> AMIs**

**Attendre que le Status passe de `pending` à `available`**

**[OK] AMI créée !**

**Noter l'AMI ID :** `ami-0a1b2c3d4e5f67890`

---

**9. Terminer l'instance template**

**EC2 -> Instances -> `web-server-template` -> Terminate instance**

**(On n'en a plus besoin, l'AMI est créée)**

---

#### Option 2 : User Data (script d'installation automatique)

**Alternative : Au lieu de créer une AMI, utiliser User Data pour installer l'app au démarrage**

**Avantage :** Pas besoin de créer/maintenir une AMI

**Inconvénient :** Temps de démarrage plus long (installation à chaque lancement)

**Pour cet exercice, on a créé une AMI (Option 1) pour des démarrages plus rapides.**

---

### ÉTAPE 3 : Créer le Launch Template

**Le Launch Template définit comment créer les instances dans l'ASG.**

---

**1. EC2 -> Launch Templates -> Create launch template**

---

**2. Launch template name and description**

**Launch template name :** `web-server-launch-template`

**Template version description :** `v1 - Ubuntu 22.04 + Apache + PHP`

**Auto Scaling guidance :** [x] Cocher

---

**3. Application and OS Images (AMI)**

**My AMIs :** Sélectionner `web-server-ami-v1`

---

**4. Instance type**

**Instance type :** `t3.micro`

**Explication :**

**t3.micro :**
- 2 vCPU
- 1 GB RAM
- Burstable (peut utiliser plus de CPU temporairement)
- $0.0104/heure = ~$7.50/mois
- Free Tier : 750 heures/mois (12 mois)

**Pourquoi t3 et pas t2 ?**

**t3** = Génération plus récente :
- Performance 30% supérieure
- Prix identique
- Meilleur ratio performance/prix

---

**5. Key pair (login)**

**Key pair name :** Sélectionner ta clé existante (ou créer)

---

**6. Network settings**

**[ATTENTION] Ne PAS configurer le VPC/Subnet ici**

Les subnets seront définis dans l'ASG.

**Security groups :** Sélectionner `web-sg` (créé précédemment)

**Ou créer un nouveau :**

**Security group name :** `asg-web-sg`

**Inbound rules :**

| Type | Port | Source | Description |
|------|------|--------|-------------|
| HTTP | 80 | 0.0.0.0/0 | From Load Balancer |
| SSH | 22 | bastion-sg | From Bastion only |

**[ATTENTION] En production, autoriser HTTP seulement depuis le Security Group du Load Balancer (pas 0.0.0.0/0)**

---

**7. Storage (volumes)**

**Volume 1 (Root) :**

**Size :** 8 GB

**Volume type :** gp3 (General Purpose SSD)

**Delete on termination :** [x] Oui

**Encrypted :** Optionnel

---

**8. Resource tags**

**Ajouter des tags pour l'organisation :**

| Key | Value |
|-----|-------|
| Name | web-server-asg |
| Environment | Production |
| ManagedBy | AutoScaling |

**[ATTENTION] IMPORTANT : Tag "Name" sera appliqué aux instances**

---

**9. Advanced details (déplier)**

**IAM instance profile :** None (pour l'instant)

**Monitoring :** [x] Enable (detailed monitoring)

**Explication :**

**Basic monitoring :** Métriques toutes les 5 minutes (gratuit)

**Detailed monitoring :** Métriques toutes les 1 minute ($0.14/instance/mois)

**Pour Auto Scaling, detailed monitoring est recommandé** (réactivité)

---

**User data (optionnel) :**

Même si on a une AMI, on peut ajouter un script pour des configurations dynamiques :

```bash
#!/bin/bash
# Script exécuté au démarrage de chaque instance

# Mettre à jour les packages
apt update -y

# Créer un fichier de version
echo "Launched at $(date)" > /var/www/html/version.txt

# Redémarrer Apache pour s'assurer qu'il tourne
systemctl restart apache2

# Envoyer des métriques custom à CloudWatch (optionnel)
# ...
```

**Pour cet exercice, on laisse vide (AMI suffit).**

---

**10. Create launch template**

**[OK] Launch Template créé !**

---

### ÉTAPE 4 : Créer l'Application Load Balancer

**Maintenant, on crée le Load Balancer qui va répartir le trafic.**

---

**1. EC2 -> Load Balancers -> Create Load Balancer**

---

**2. Sélectionner le type : Application Load Balancer**

**Create**

---

**3. Basic configuration**

**Load balancer name :** `web-app-alb`

**Scheme :** Internet-facing

**Explication des schemes :**

**Internet-facing :**
- Accessible depuis Internet
- IP publiques
- Pour applications web publiques

**Internal :**
- Accessible seulement depuis le VPC
- IP privées
- Pour services internes (ex: API backend)

**Pour cet exercice : Internet-facing**

---

**IP address type :** IPv4

---

**4. Network mapping**

**VPC :** `multi-tier-vpc` (ou default)

**Mappings (Availability Zones) :**

**[x] us-east-1a :** Sélectionner `public-subnet-1a`

**[x] us-east-1b :** Sélectionner `public-subnet-1b`

**Explication :**

Le Load Balancer doit être dans des **subnets publics** (avec accès Internet).

**Multi-AZ essentiel pour HA :**

Si une AZ tombe, le LB continue dans l'autre AZ.

---

**5. Security groups**

**Créer un nouveau Security Group pour le Load Balancer :**

**Security group name :** `alb-sg`

**Inbound rules :**

| Type | Port | Source | Description |
|------|------|--------|-------------|
| HTTP | 80 | 0.0.0.0/0 | Public web traffic |
| HTTPS | 443 | 0.0.0.0/0 | Public HTTPS (optionnel) |

**Outbound rules :**

| Type | Port | Destination | Description |
|------|------|-------------|-------------|
| HTTP | 80 | asg-web-sg | To web servers |

---

**Ou sélectionner un SG existant si déjà créé.**

---

**6. Listeners and routing**

**Listener :**

**Protocol :** HTTP

**Port :** 80

**Default action :** Forward to... (on va créer un Target Group)

---

**Créer un Target Group :**

**Cliquer sur "Create target group" (ouvre un nouvel onglet)**

---

**7. Target Group - Step 1 : Specify group details**

**Choose a target type :** Instances

**Target group name :** `web-servers-tg`

**Protocol :** HTTP

**Port :** 80

**VPC :** `multi-tier-vpc`

**Protocol version :** HTTP1

---

**Health checks**

**Health check protocol :** HTTP

**Health check path :** `/`

**[ATTENTION] Important : S'assurer que cette page répond HTTP 200**

---

**Advanced health check settings (déplier) :**

**Healthy threshold :** 2 (2 checks successifs OK -> Healthy)

**Unhealthy threshold :** 3 (3 checks successifs KO -> Unhealthy)

**Timeout :** 5 seconds

**Interval :** 30 seconds (vérifier toutes les 30s)

**Success codes :** 200

---

**Explication Health Checks :**

**Flow :**

```
1. LB envoie GET / HTTP/1.1
2. Si réponse 200 OK dans < 5s -> Check réussi
3. Si 2 checks réussis consécutifs -> Instance Healthy
4. Si timeout ou erreur -> Check échoué
5. Si 3 checks échoués consécutifs -> Instance Unhealthy
   -> Retirer du pool (ne plus envoyer de trafic)
```

**Interval 30s :**

Vérifier toutes les 30 secondes (ni trop souvent, ni trop rare).

**Pourquoi 2/3 et pas 1/1 ?**

Éviter les faux positifs (réseau temporairement lent, etc.).

---

**Next**

---

**8. Target Group - Step 2 : Register targets**

**[ATTENTION] Ne PAS enregistrer d'instances maintenant**

L'Auto Scaling Group le fera automatiquement.

**Next**

---

**9. Target Group - Step 3 : Review**

**Create target group**

**[OK] Target Group créé !**

**Fermer cet onglet, revenir à la création du Load Balancer.**

---

**10. Retour dans Load Balancer - Listener**

**Rafraîchir la liste des Target Groups**

**Default action :** Forward to -> `web-servers-tg`

---

**11. Tags (optionnel)**

| Key | Value |
|-----|-------|
| Name | web-app-alb |
| Environment | Production |

---

**12. Summary -> Create load balancer**

**[OK] Load Balancer créé !**

**[HOURGLASS_WITH_FLOWING_SAND] État : Provisioning... (2-3 minutes)**

**Attendre que le State passe à `Active`**

---

**13. Récupérer le DNS du Load Balancer**

**EC2 -> Load Balancers -> web-app-alb**

**DNS name :** `web-app-alb-123456789.us-east-1.elb.amazonaws.com`

*** Copier ce DNS (URL publique du site)**

---

### ÉTAPE 5 : Créer l'Auto Scaling Group

**Maintenant, on crée l'ASG qui va gérer les instances automatiquement.**

---

**1. EC2 -> Auto Scaling Groups -> Create Auto Scaling group**

---

**2. Step 1 : Choose launch template**

**Auto Scaling group name :** `web-servers-asg`

**Launch template :** `web-server-launch-template`

**Version :** Latest (ou Default)

**Next**

---

**3. Step 2 : Choose instance launch options**

**Network**

**VPC :** `multi-tier-vpc`

**Availability Zones and subnets :**

**[x] public-subnet-1a** (us-east-1a)

**[x] public-subnet-1b** (us-east-1b)

**[ATTENTION] Sélectionner au moins 2 subnets dans 2 AZ différentes (HA)**

---

**Instance type requirements (optionnel) :**

Laisser vide (on utilise ce qui est dans le Launch Template : t3.micro)

**Next**

---

**4. Step 3 : Configure advanced options**

**Load balancing**

**[x] Attach to an existing load balancer**

**Existing load balancer target groups :**

**Choose from your load balancer target groups :** `web-servers-tg`

---

**Health checks**

**[x] Turn on Elastic Load Balancing health checks**

**Health check grace period :** 300 seconds

**Explication :**

**Grace period** = Temps d'attente avant de vérifier la santé d'une nouvelle instance.

**300s = 5 minutes** -> Le temps pour l'instance de démarrer et être prête.

Si on vérifie trop tôt, l'instance sera marquée Unhealthy alors qu'elle démarre encore.

---

**[ATTENTION] 2 types de health checks :**

**EC2 status checks :**
- Vérifie que l'instance EC2 tourne (hardware, hypervisor)
- Basique

**ELB health checks :**
- Vérifie que l'application web répond (HTTP 200)
- Plus fiable (détecte si Apache est down)

**Recommandation : Activer ELB health checks** [OK]

---

**Additional settings**

**Monitoring**

**[x] Enable group metrics collection within CloudWatch**

**Permet de voir les métriques de l'ASG dans CloudWatch.**

---

**Next**

---

**5. Step 4 : Configure group size and scaling policies**

**Group size**

**Desired capacity :** 2

**Minimum capacity :** 2

**Maximum capacity :** 10

**Explication :**

**Desired = 2 :**

Au démarrage, l'ASG lance 2 instances.

**Minimum = 2 :**

Il y aura toujours au moins 2 instances (HA).

Même si charge très faible, ne jamais descendre en dessous de 2.

**Maximum = 10 :**

Limite pour éviter les coûts excessifs.

Même si CPU à 100%, ne jamais dépasser 10 instances.

---

**Scaling policies**

**[x] Target tracking scaling policy**

**Policy name :** `target-cpu-50`

**Metric type :** Average CPU utilization

**Target value :** 50 %

**Explication :**

**"Maintenir le CPU moyen à 50%"**

**Si CPU > 50% :**
- ASG lance des instances supplémentaires
- Le trafic est réparti sur plus de serveurs
- CPU redescend vers 50%

**Si CPU < 50% :**
- ASG termine des instances (respecte le minimum de 2)
- Économie de coûts

---

**Instances need (seconds) :** 300

**Warmup time** avant que les métriques de la nouvelle instance soient prises en compte.

---

**[x] Disable scale-in** : Décocher

**Laisser décoché pour autoriser le scale-in (retrait d'instances).**

---

**Scaling policies - Options avancées (optionnel)**

**Cliquer sur "Add another scaling policy"** (optionnel)

**Step scaling ou Simple scaling :**

Exemple Step Scaling :

```
CloudWatch Alarm: CPUUtilization > 70%
  Action: Add 1 instance
  Cooldown: 300 seconds

CloudWatch Alarm: CPUUtilization > 90%
  Action: Add 2 instances
  Cooldown: 180 seconds

CloudWatch Alarm: CPUUtilization < 30%
  Action: Remove 1 instance
  Cooldown: 300 seconds
```

**Pour cet exercice, Target Tracking suffit** (plus simple).

---

**Next**

---

**6. Step 5 : Add notifications (optionnel)**

**Recevoir des notifications SNS quand l'ASG scale.**

**Create topic**

**Send a notification to :** `asg-notifications`

**Email :** ton.email@example.com

**Next**

**Tu recevras un email de confirmation -> Confirmer l'abonnement**

---

**Ou skip : Next**

---

**7. Step 6 : Add tags**

**Add tag :**

| Key | Value | Tag new instances |
|-----|-------|-------------------|
| Name | web-server-asg | [x] Oui |
| Environment | Production | [x] Oui |

**Le tag sera appliqué aux instances lancées par l'ASG.**

**Next**

---

**8. Step 7 : Review**

**Vérifier toute la configuration**

**Create Auto Scaling group**

**[OK] Auto Scaling Group créé !**

---

**9. Vérifier le lancement des instances**

**Auto Scaling Groups -> web-servers-asg -> Instance management**

**Status : En cours de lancement...**

**Attendre 2-3 minutes**

**Tu devrais voir 2 instances :**

```
Instance ID          AZ           Health Status   Lifecycle
i-0a1b2c3d4e5f6789   us-east-1a   Healthy        InService
i-9z8y7x6w5v4u3t2   us-east-1b   Healthy        InService
```

**[OK] 2 instances lancées automatiquement ! ***

---

**10. Vérifier dans le Target Group**

**EC2 -> Target Groups -> web-servers-tg -> Targets**

**Tu devrais voir les 2 instances avec Status = Healthy**

```
Target ID           Zone        Health Status
i-0a1b2c3d...       us-east-1a  Healthy
i-9z8y7x6w...       us-east-1b  Healthy
```

**Si Status = Initial :**

Attendre 1-2 minutes (health checks en cours).

**Si Status = Unhealthy :**

Problème : Voir section Troubleshooting.

---

### ÉTAPE 6 : Tester le Load Balancer

**Maintenant, testons que tout fonctionne !**

---

**Test 1 : Accéder au site via le Load Balancer**

**Ouvrir dans le navigateur :**

```
http://web-app-alb-123456789.us-east-1.elb.amazonaws.com
```

**Remplacer par le DNS de ton ALB.**

**[OK] Page web affichée !**

**Tu devrais voir :**

- **Serveur :** ip-10-0-1-123 (hostname de l'instance)
- **Adresse IP :** 10.0.1.123
- etc.

---

**Test 2 : Vérifier la répartition de charge**

**Rafraîchir la page plusieurs fois (F5)**

**Observe le "Serveur" (hostname) :**

```
1ère requête : Serveur ip-10-0-1-123
2ème requête : Serveur ip-10-0-11-45
3ème requête : Serveur ip-10-0-1-123
4ème requête : Serveur ip-10-0-11-45
```

**Le hostname change ! ***

**Le Load Balancer répartit les requêtes entre les 2 instances ! [OK]**

---

**[ATTENTION] Si le hostname ne change jamais :**

**Cause possible : Sticky sessions activées**

**Vérification :**

EC2 -> Target Groups -> web-servers-tg -> Attributes

**Stickiness :** Si activé, le désactiver

**Edit -> Stickiness : Off -> Save changes**

**Rafraîchir -> Le hostname devrait changer maintenant**

---

**Test 3 : Simuler la panne d'une instance**

**EC2 -> Instances**

**Sélectionner une des 2 instances de l'ASG**

**Instance state -> Stop instance**

**[HOURGLASS_WITH_FLOWING_SAND] Instance en cours d'arrêt...**

---

**Pendant l'arrêt, rafraîchir le site dans le navigateur**

**[OK] Le site reste accessible !**

**Le Load Balancer redirige tout le trafic vers l'instance restante.**

---

**Attendre 2-3 minutes**

**EC2 -> Auto Scaling Groups -> web-servers-asg -> Activity**

**Tu devrais voir :**

```
Status      Description
Successful  Launching a new EC2 instance: i-xyz...
```

**[OK] L'ASG a automatiquement lancé une nouvelle instance pour remplacer celle arrêtée ! ***

**Auto-healing fonctionne !**

---

**Test 4 : Vérifier les logs CloudWatch du Load Balancer**

**S3 -> Buckets (les logs ALB peuvent être envoyés vers S3)**

**Ou CloudWatch -> Log Insights** (si configuré)

**Voir les requêtes HTTP, codes status, latence, etc.**

---

### ÉTAPE 7 : Tester l'Auto Scaling avec charge

**Maintenant, simulons une charge élevée pour déclencher le scale-out.**

---

**Option 1 : Utiliser le stress test intégré**

**Dans le navigateur :**

```
http://web-app-alb-xxx.elb.amazonaws.com
```

**Cliquer sur "[RAPIDE] Démarrer le test"**

**Le serveur calcule des nombres premiers pendant 30 secondes -> CPU monte.**

**Ouvrir plusieurs onglets (10-20) et lancer le test sur chacun.**

---

**Option 2 : Utiliser stress-ng (outil de stress)**

**Se connecter à une instance via SSH (via Bastion si privée)**

```bash
# Installer stress-ng
sudo apt install -y stress-ng

# Stresser le CPU pendant 10 minutes
stress-ng --cpu 2 --timeout 600s --metrics-brief
```

---

**Option 3 : Utiliser Apache Bench (load testing)**

**Depuis ta machine locale :**

```bash
# Installer Apache Bench
# macOS : brew install httpd
# Linux : apt install apache2-utils

# Envoyer 10,000 requêtes avec 100 connexions concurrentes
ab -n 10000 -c 100 http://web-app-alb-xxx.elb.amazonaws.com/
```

**Cela génère beaucoup de trafic -> CPU monte -> Scale out**

---

**Option 4 : Utiliser Locust (load testing avancé)**

**Installation :**

```bash
pip install locust
```

**Créer un fichier `locustfile.py` :**

```python
from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 2)  # 1-2 secondes entre requêtes
    
    @task(3)
    def index(self):
        self.client.get("/")
    
    @task(1)
    def stress(self):
        self.client.get("/stress.php")
```

**Lancer Locust :**

```bash
locust -f locustfile.py --host=http://web-app-alb-xxx.elb.amazonaws.com
```

**Ouvrir http://localhost:8089**

**Interface web pour configurer :**
- Number of users : 100
- Spawn rate : 10 users/second

**Start swarming**

**Génère une charge massive ! [HOT]**

---

**Monitorer l'Auto Scaling :**

**CloudWatch -> Dashboards (ou All metrics)**

**Métriques à surveiller :**

**EC2 -> By Auto Scaling Group -> web-servers-asg**

**Métriques :**

| Métrique | Signification | Seuil Scale Out |
|----------|---------------|-----------------|
| CPUUtilization | % CPU moyen | > 50% |
| NetworkIn | Octets entrants | > 10 MB/s |
| NetworkOut | Octets sortants | > 10 MB/s |

**ApplicationELB -> Per AppELB Metrics**

| Métrique | Signification |
|----------|---------------|
| RequestCount | Nombre de requêtes |
| TargetResponseTime | Latence moyenne |
| HealthyHostCount | Nombre d'instances saines |
| UnHealthyHostCount | Nombre d'instances malsaines |

---

**Observer le scale-out :**

**CloudWatch -> CPU Utilization monte progressivement...**

```
11:00 - CPU: 45%
11:02 - CPU: 55%
11:04 - CPU: 65%
11:06 - CPU: 75% <- Dépasse le seuil (50%)
11:08 - CloudWatch Alarm déclenché
11:10 - ASG lance +1 instance
11:12 - Instance démarre...
11:15 - Instance Healthy, ajoutée au LB
11:17 - Trafic réparti sur 3 instances
11:19 - CPU redescend à 50%
```

---

**Auto Scaling Groups -> web-servers-asg -> Activity**

**Tu devrais voir :**

```
Status        Description
Successful    Launching a new EC2 instance: i-abc...
              Cause: At 2025-01-08 11:08 an instance was started in response 
                     to a difference between desired and actual capacity, 
                     increasing the capacity from 2 to 3.
```

**[OK] Scale-out réussi ! Une 3ème instance a été lancée ! ***

---

**EC2 -> Instances**

**Tu devrais maintenant voir 3 instances en cours d'exécution.**

---

**Attendre que la charge diminue (arrêter les tests)**

**Après 10-15 minutes, si CPU < 50% :**

**ASG va automatiquement scale-in (retirer une instance).**

**Activity :**

```
Status        Description
Successful    Terminating EC2 instance: i-abc...
              Cause: At 2025-01-08 11:35 a monitor alarm TargetTracking-...
                     in state ALARM triggered policy target-cpu-50 changing 
                     the desired capacity from 3 to 2.
```

**[OK] Scale-in réussi ! Retour à 2 instances. ***

**Le cycle est complet : Scale Out -> Scale In -> Économie**

---

### ÉTAPE 8 : Configurer des CloudWatch Alarms

**Créer des alarmes pour être notifié des événements importants.**

---

**Alarm 1 : CPU élevé**

**CloudWatch -> Alarms -> Create alarm**

**Select metric -> EC2 -> By Auto Scaling Group -> CPUUtilization**

**Sélectionner `web-servers-asg`**

**Select metric**

---

**Conditions :**

**Threshold type :** Static

**Whenever CPUUtilization is :** Greater than 80

**Next**

---

**Notification :**

**Send a notification to :** asg-notifications (SNS topic)

**Next**

---

**Alarm name :** `ASG-HighCPU`

**Alarm description :** `CPU > 80% on ASG`

**Create alarm**

**[OK] Alarm créé !**

**Si CPU > 80%, tu recevras un email.**

---

**Alarm 2 : Aucune instance saine**

**Create alarm**

**Select metric -> ApplicationELB -> Per AppELB -> HealthyHostCount**

**Sélectionner `web-app-alb` et `web-servers-tg`**

**Select metric**

---

**Conditions :**

**Whenever HealthyHostCount is :** Lower than 1

**Next**

---

**Notification :** asg-notifications

**Alarm name :** `ALB-NoHealthyHosts`

**Create alarm**

**[OK] Si toutes les instances deviennent unhealthy, tu seras alerté.**

---

**Alarm 3 : Latence élevée**

**Create alarm**

**ApplicationELB -> Per AppELB -> TargetResponseTime**

**Conditions :**

**Greater than :** 1 (secondes)

**Notification :** asg-notifications

**Alarm name :** `ALB-HighLatency`

**Create alarm**

**[OK] Si latence > 1s, alarme déclenchée.**

---

### ÉTAPE 9 : Optimiser les coûts

**L'Auto Scaling économise de l'argent, mais on peut optimiser encore plus.**

---

**1. Utiliser Scheduled Scaling**

**Si charge prévisible (ex: 9h-18h en semaine), utiliser Scheduled Actions.**

**Auto Scaling Groups -> web-servers-asg -> Automatic scaling -> Scheduled actions**

**Create scheduled action**

---

**Name :** `scale-up-business-hours`

**Desired capacity :** 4

**Min :** 4

**Max :** 10

**Recurrence :** Cron expression

**Cron :** `0 9 * * MON-FRI` (Tous les jours de semaine à 9h)

**Time zone :** (Ta timezone)

**Create**

---

**Create another scheduled action :**

**Name :** `scale-down-night`

**Desired capacity :** 2

**Min :** 2

**Max :** 10

**Cron :** `0 18 * * MON-FRI` (Tous les jours de semaine à 18h)

**Create**

---

**Résultat :**

```
Lundi-Vendredi 9h-18h : 4 instances minimum (charge business)
Nuit et weekend : 2 instances (économie)
```

---

**2. Utiliser des Spot Instances**

**Spot Instances** = Capacité EC2 inutilisée à prix réduit (jusqu'à -90%)

**Risque :** AWS peut reprendre l'instance avec 2 minutes de préavis.

**Solution : Mix On-Demand + Spot**

**Launch Template -> Create new version**

**Advanced details -> Purchasing options**

**[x] Request Spot Instances**

**Maximum price :** (Laisser vide = prix Spot actuel)

**Interruption behavior :** Terminate

**Create template version**

---

**Auto Scaling Group -> Edit**

**Instance type requirements (optional) -> Override launch template**

**On-Demand base capacity :** 2 (Toujours 2 On-Demand pour stabilité)

**On-Demand percentage above base :** 0% (Tout le reste en Spot)

**Spot allocation strategy :** Price capacity optimized

**Save**

---

**Résultat :**

```
2 instances On-Demand (toujours présentes)
+
X instances Spot (jusqu'à maximum capacity)
```

**Économie : ~70-80% sur les instances Spot !**

---

**3. Utiliser des Savings Plans ou Reserved Instances**

**Si charge stable (ex: minimum 2 instances 24/7) :**

**EC2 -> Reserved Instances -> Purchase Reserved Instances**

**Instance type :** t3.micro

**Term :** 1 year

**Payment option :** All Upfront

**Savings :** ~30-40%

---

**Ou Savings Plans (plus flexible) :**

**AWS Cost Management -> Savings Plans -> Purchase Savings Plans**

**Commitment :** $5/month

**Term :** 1 year

**Savings :** ~30-72%

---

**4. Right-sizing des instances**

**Surveiller les métriques CPU/RAM**

**Si CPU toujours < 20% :**

Peut-être que t3.micro est surdimensionné -> Passer à t3.nano ($3.75/mois)

**Si CPU souvent > 80% même avec scaling :**

Peut-être sous-dimensionné -> Passer à t3.small ($15/mois)

**Utiliser AWS Compute Optimizer (recommandations auto)**

---

### ÉTAPE 10 : Calculer les coûts

**Composants payants :**

| Service | Coût | Calcul mensuel |
|---------|------|----------------|
| **ALB** | $0.0225/heure + LCU | $16.20 + LCU |
| **EC2 t3.micro** | $0.0104/heure | $7.59/instance |
| **EBS gp3 8GB** | $0.08/GB-mois | $0.64/instance |
| **Data transfer OUT** | $0.09/GB après 1GB | Variable |
| **Detailed monitoring** | $0.14/instance/mois | $0.14/instance (optionnel) |

**LCU** = Load Balancer Capacity Unit

**Calcul des LCU (complexe) :**

LCU basé sur la plus haute des 4 dimensions :
- New connections/sec
- Active connections/min
- Processed bytes/hour
- Rule evaluations/sec

**Approximation : ~$5-15/mois pour petite app**

---

**Scénario 1 : Charge faible (2 instances 24/7)**

**ALB :**
- Fixed : 730h × $0.0225 = $16.43
- LCU : ~$5 (estimation)
- Total ALB : **$21.43**

**EC2 (2 instances) :**
- Instances : 2 × 730h × $0.0104 = $15.18
- EBS : 2 × 8GB × $0.08 = $1.28
- Monitoring : 2 × $0.14 = $0.28 (optionnel)
- Total EC2 : **$16.74**

**Data transfer :**
- 100 GB × $0.09 = $9 (après 1 GB gratuit)

**TOTAL : $21.43 + $16.74 + $9 = $47.17/mois**

**Avec Free Tier (12 mois) :**
- 750h EC2 gratuit couvre 1 instance complète
- Économie : -$7.59
- **Total avec FT : $39.58/mois**

---

**Scénario 2 : Charge variable (2-6 instances, moyenne 3)**

**ALB :** $21.43

**EC2 :**
- Moyenne 3 instances
- 3 × 730h × $0.0104 = $22.78
- EBS : 3 × $1.28 = $3.84
- Total EC2 : **$26.62**

**Data transfer :** $15

**TOTAL : $21.43 + $26.62 + $15 = $63.05/mois**

---

**Scénario 3 : Black Friday (10 instances pendant 24h)**

**Surcoût pour 24h :**

**Instances supplémentaires : (10 - 2) = 8 instances × 24h**

- 8 × 24h × $0.0104 = $1.99

**Total Black Friday : $63.05 + $1.99 = $65.04 pour le mois**

**-> Seulement +$1.99 pour gérer le pic ! ***

**Sans Auto Scaling (10 instances 24/7) :**

10 × $7.59 = $75.90 **juste pour les instances**

**Économie Auto Scaling : ~$50/mois !**

---

**Comparaison architectures :**

| Architecture | Coût/mois | Disponibilité | Scalabilité |
|--------------|-----------|---------------|-------------|
| 1 instance EC2 | $8 | 99% (1 AZ) | [X] Aucune |
| 2 instances manuelles | $16 | 99.9% (Multi-AZ) | [X] Manuelle |
| ALB + ASG (2-10) | $40-65 | 99.95%+ | [OK] Auto |

**ROI évident pour production ! ***

---

### [OK] TESTS DE VALIDATION

**1. Infrastructure**

- [ ] ALB créé dans 2 AZ avec DNS fonctionnel
- [ ] Target Group créé avec health checks configurés
- [ ] Launch Template créé avec AMI personnalisée
- [ ] ASG créé avec min 2, max 10, desired 2

---

**2. Haute Disponibilité**

- [ ] 2 instances lancées dans 2 AZ différentes
- [ ] Instances enregistrées dans Target Group (Healthy)
- [ ] Site accessible via DNS du Load Balancer
- [ ] Hostname change lors du rafraîchissement (load balancing)
- [ ] Arrêt d'une instance -> Site reste accessible
- [ ] ASG lance automatiquement une nouvelle instance (auto-healing)

---

**3. Auto Scaling**

- [ ] Scaling policy Target Tracking CPU 50% configurée
- [ ] Test de charge génère CPU > 50%
- [ ] CloudWatch Alarm déclenché
- [ ] ASG lance une nouvelle instance (scale-out)
- [ ] Charge diminue -> ASG termine une instance (scale-in)
- [ ] Minimum 2 instances toujours maintenu

---

**4. Monitoring**

- [ ] CloudWatch metrics visibles (CPU, Network, RequestCount)
- [ ] CloudWatch Alarms créées (CPU élevé, No healthy hosts, Latence)
- [ ] SNS topic configuré avec email de notification
- [ ] Activity history dans ASG montre les actions de scaling

---

**5. Sécurité**

- [ ] Security Group ALB autorise HTTP/HTTPS depuis Internet
- [ ] Security Group instances autorise HTTP depuis ALB uniquement
- [ ] Security Group instances autorise SSH depuis Bastion uniquement
- [ ] Instances dans subnets publics/privés appropriés

---

### [ROUGE] ERREURS COURANTES ET SOLUTIONS

#### Erreur 1 : Instances Unhealthy dans Target Group

**Symptôme :**

Target Group -> Targets -> Status = Unhealthy

**Causes possibles :**

**1. Health check path invalide**

Health check vers `/` mais la page n'existe pas ou retourne erreur.

**Solution :**

Créer une page `/health.html` simple :

```bash
echo "OK" | sudo tee /var/www/html/health.html
```

Target Group -> Health checks -> Edit

Health check path : `/health.html`

---

**2. Security Group bloque le health check**

Le Security Group des instances ne permet pas le trafic depuis l'ALB.

**Solution :**

EC2 -> Security Groups -> asg-web-sg -> Inbound rules

Vérifier qu'il y a :

| Type | Port | Source | Description |
|------|------|--------|-------------|
| HTTP | 80 | alb-sg | From ALB |

Ou : Source = 0.0.0.0/0 (moins sécurisé mais fonctionne)

---

**3. Apache ne tourne pas**

L'application web n'est pas démarrée.

**Solution :**

Se connecter à l'instance :

```bash
sudo systemctl status apache2
```

Si arrêté :

```bash
sudo systemctl start apache2
sudo systemctl enable apache2
```

---

**4. Grace period trop court**

Les instances sont marquées Unhealthy avant d'être prêtes.

**Solution :**

ASG -> Edit -> Health check grace period : 300 -> 600 seconds

---

#### Erreur 2 : Auto Scaling ne scale pas

**Symptôme :**

CPU > 70% mais aucune nouvelle instance lancée.

**Causes possibles :**

**1. Maximum capacity atteint**

ASG -> Déjà 10 instances (maximum).

**Solution :**

Edit -> Maximum capacity : 20 (augmenter)

---

**2. Scaling policy mal configurée**

Target value trop élevé (ex: CPU target 90%).

**Solution :**

ASG -> Automatic scaling -> Edit policy

Target value : 50% (au lieu de 90%)

---

**3. Cooldown period**

ASG attend la fin du cooldown avant de scaler à nouveau.

**Solution :**

Attendre 5-10 minutes (cooldown par défaut 300s).

Ou réduire le cooldown (mais attention aux oscillations).

---

**4. Pas de CloudWatch Alarm**

La policy n'a pas créé d'alarm.

**Solution :**

CloudWatch -> Alarms -> Vérifier qu'il y a bien une alarm `TargetTracking-...`

Si absente, supprimer et recréer la scaling policy.

---

#### Erreur 3 : 503 Service Unavailable

**Symptôme :**

Navigateur affiche "503 Service Temporarily Unavailable".

**Causes :**

**1. Aucune instance Healthy**

Toutes les instances sont Unhealthy ou terminées.

**Solution :**

Voir "Erreur 1 : Instances Unhealthy".

---

**2. Target Group vide**

ASG n'a pas encore lancé d'instances ou elles ne sont pas enregistrées.

**Solution :**

ASG -> Activity -> Vérifier qu'il y a des instances "InService".

Si non, ASG -> Edit -> Desired capacity : 2

---

#### Erreur 4 : Site très lent malgré plusieurs instances

**Symptôme :**

ALB répartit le trafic mais les réponses sont lentes.

**Causes possibles :**

**1. Base de données surchargée**

Les instances web sont OK mais la DB est le bottleneck.

**Solution :**

RDS -> Augmenter l'instance type (db.t3.small -> db.t3.medium)

Ou utiliser Read Replicas.

---

**2. Code inefficace**

Application PHP/Python fait des calculs lourds.

**Solution :**

Optimiser le code, utiliser cache (Redis/Memcached).

---

**3. Toutes les instances dans 1 AZ**

Network bottleneck dans une AZ.

**Solution :**

ASG -> Edit -> Subnets -> Sélectionner 2+ AZ.

---

#### Erreur 5 : Coûts élevés

**Symptôme :**

Facture AWS beaucoup plus élevée que prévu.

**Causes :**

**1. Maximum capacity trop élevé**

ASG a lancé 50 instances (max mal configuré).

**Solution :**

ASG -> Edit -> Maximum capacity : 10 (limite raisonnable)

---

**2. Scale-in désactivé**

Instances lancées mais jamais terminées.

**Solution :**

ASG -> Scaling policies -> Vérifier que "Disable scale-in" est décoché.

---

**3. Data transfer OUT élevé**

Beaucoup de trafic sortant (vidéos, gros fichiers).

**Solution :**

Utiliser CloudFront (CDN) pour réduire data transfer.

---

### [IMPORTANT] POINTS CLÉS À RETENIR

**1. Haute Disponibilité = Multi-AZ + Redondance**
- Déployer dans plusieurs AZ (us-east-1a, 1b, 1c)
- Éliminer les Single Points of Failure (SPOF)
- Minimum 2 instances pour HA

**2. Load Balancer = Répartition intelligente du trafic**
- ALB (Layer 7) pour applications web/APIs
- NLB (Layer 4) pour performance extrême/non-HTTP
- Health checks toutes les 30s (détection pannes)

**3. Auto Scaling = Ajustement automatique de capacité**
- Scale Out : Ajouter instances si charge élevée
- Scale In : Retirer instances si charge faible
- Target Tracking Scaling = Le plus simple (maintenir CPU à X%)

**4. Launch Template = Blueprint des instances**
- AMI, instance type, security groups, user data
- Versionné (rollback possible)

**5. Target Group = Pool d'instances backend**
- Enregistrement automatique par ASG
- Health checks pour retirer instances malsaines
- Métriques (RequestCount, Latency, HealthyHostCount)

**6. Scaling Policies types**
- Target Tracking : Maintenir une métrique (CPU, latence)
- Step Scaling : Règles graduelles (50-70%, 70-90%)
- Simple Scaling : Une règle simple (si CPU > X, +1 instance)
- Scheduled : Scaler à heures fixes (9h-18h)

**7. Health Checks = Surveillance santé**
- ELB health checks (HTTP 200 sur /health)
- EC2 status checks (hardware/hypervisor)
- Grace period pour laisser instances démarrer

**8. Coûts**
- ALB : ~$21/mois (fixed + LCU)
- EC2 : ~$8/instance/mois (t3.micro)
- Auto Scaling économise 50-80% vs capacité fixe

**9. Monitoring**
- CloudWatch Metrics (CPU, Network, RequestCount)
- CloudWatch Alarms (alertes SNS)
- ASG Activity History (audit scaling)

**10. Optimisations**
- Scheduled Scaling (charge prévisible)
- Spot Instances (économie -70%)
- Reserved Instances/Savings Plans (engagement -30-40%)
- Right-sizing (ajuster taille instances)

---

### [RAPIDE] POUR ALLER PLUS LOIN

**1. Connection Draining / Deregistration Delay**

**Problème :**

Quand une instance est retirée, elle traite peut-être encore des requêtes.

Si terminée immédiatement -> Erreurs pour les clients.

**Solution : Deregistration Delay**

Target Group -> Attributes -> Edit

**Deregistration delay :** 300 seconds

**Comportement :**

1. ASG veut terminer l'instance
2. Target Group marque l'instance "Draining"
3. Nouvelles requêtes -> Autres instances
4. Requêtes en cours -> Continuer sur l'instance "Draining"
5. Attendre 300s (ou fin de toutes les requêtes)
6. Terminer l'instance

**Terminaison gracieuse ! [OK]**

---

**2. Sticky Sessions (Session Affinity)**

**Problème :**

User se connecte -> Session PHP stockée sur Serveur 1

Requête suivante -> Load Balancer redirige vers Serveur 2 -> Session perdue !

**Solution : Sticky Sessions**

Target Group -> Attributes -> Edit

**Stickiness :** Enable

**Stickiness type :** Load balancer generated cookie

**Stickiness duration :** 1 hour

**Comportement :**

1. User visite site -> Redirigé vers Serveur 1
2. ALB envoie cookie : AWSALB=xyz123...
3. Requêtes suivantes avec ce cookie -> Toujours Serveur 1
4. Après 1 heure -> Cookie expire -> Peut changer de serveur

**[ATTENTION] Inconvénient : Répartition moins équilibrée**

**Alternative moderne : Sessions externes (Redis, ElastiCache)**

---

**3. SSL/TLS Termination**

**Chiffrer le trafic avec HTTPS**

**Obtenir un certificat SSL :**

**Option 1 : AWS Certificate Manager (ACM) - GRATUIT**

ACM -> Request certificate

**Certificate type :** Request a public certificate

**Domain name :** www.monsite.com

**Validation method :** DNS validation (recommandé) ou Email

**Request**

**Valider le certificat** (ajouter CNAME dans Route 53 ou DNS provider)

**[HOURGLASS_WITH_FLOWING_SAND] Certificate Status : Issued**

---

**Ajouter HTTPS à l'ALB :**

Load Balancers -> web-app-alb -> Listeners

**Add listener**

**Protocol :** HTTPS

**Port :** 443

**Default action :** Forward to web-servers-tg

**Security policy :** ELBSecurityPolicy-2016-08 (recommandé)

**Default SSL certificate :** From ACM -> Sélectionner le certificat

**Add**

---

**Rediriger HTTP -> HTTPS :**

Listener HTTP:80 -> Edit rules

**Add rule**

**IF :** Host is `www.monsite.com`

**THEN :** Redirect to HTTPS (Port 443, Status 301 Permanent)

**Save**

**Maintenant, tout le trafic est chiffré ! [VERROUILLE]**

---

**4. Web Application Firewall (WAF)**

**Protéger l'ALB contre les attaques (SQL injection, XSS, etc.)**

WAF & Shield -> AWS WAF -> Web ACLs

**Create web ACL**

**Resource type :** Regional resources (Application Load Balancer)

**Associated AWS resources :** `web-app-alb`

**Rules :**

**Add managed rule groups :**
- [x] AWS Managed Rules - Core rule set (CRS)
- [x] AWS Managed Rules - SQL database
- [x] AWS Managed Rules - Known bad inputs

**Create web ACL**

**Coût :** $5/mois + $1/million requests

**L'ALB est maintenant protégé contre les attaques courantes ! [SECURITE]**

---

**5. AWS Shield (Protection DDoS)**

**AWS Shield Standard** : Gratuit, activé automatiquement

Protège contre les attaques DDoS courantes (Layer 3/4).

**AWS Shield Advanced** : $3,000/mois

Protection DDoS avancée + équipe de réponse AWS + garantie de coûts.

**Pour la plupart des apps : Shield Standard suffit.**

---

**6. Global Accelerator**

**Améliorer la performance globale (latence)**

**Problème :**

Users en Europe -> DNS vers ALB us-east-1 -> Latence élevée (150-200ms)

**Solution : AWS Global Accelerator**

**Global Accelerator** = Réseau privé AWS global + Anycast IPs

**Flux :**

```
User Europe -> Edge Location Europe (Anycast IP)
   v (AWS Global Network - fibre privée)
ALB us-east-1 (latence réduite 30-50ms)
```

**Coût :** $0.025/heure + $0.015/GB data transfer premium

**Latence réduite de 60% ! [RAPIDE]**

---

**7. Cross-Region Failover**

**Haute disponibilité inter-régions**

**Architecture :**

```
Route 53 (DNS avec health checks)
   v               v
ALB us-east-1   ALB eu-west-1 (backup)
   v               v
ASG Primary     ASG Secondary
```

**Route 53 -> Health checks :**

Si us-east-1 down -> Rediriger automatiquement vers eu-west-1

**Disponibilité 99.99%+ ! [GEM_STONE]**

---

**8. Blue/Green Deployment**

**Déployer une nouvelle version sans downtime**

**Processus :**

1. **Blue Environment** : Production actuelle (ASG v1)
2. Créer **Green Environment** : Nouvelle version (ASG v2)
3. Tester Green en isolation
4. ALB -> Basculer Target Group : Blue -> Green
5. Si problème -> Rollback instant (rebasculer vers Blue)
6. Si OK -> Terminer Blue

**Déploiement zero-downtime ! [RAPIDE]**

---

**9. Container-based Auto Scaling**

**Pour applications containerisées (Docker)**

**ECS (Elastic Container Service) + ALB :**

Similaire à EC2 ASG mais pour containers.

**ECS Service Auto Scaling :**
- Task-based scaling (nombre de containers)
- Target Tracking sur CPU/RAM
- Plus léger et flexible qu'EC2

**Ou Fargate (serverless containers) :**

Pas besoin de gérer EC2, seulement les containers.

---

**10. Lambda + ALB**

**Pour APIs serverless**

**ALB peut router vers Lambda Functions**

**Avantage :**

Mix EC2 + Lambda dans le même ALB :

```
/api/* -> Lambda (serverless, scale infini)
/admin/* -> EC2 (apps complexes)
```

**Flexibilité maximale ! [OBJECTIF]**

---

## [COURS] CONCLUSION DE L'EXERCICE 6

**[BRAVO] Bravo ! Tu as créé une architecture hautement disponible et auto-scalable ! [BRAVO]**

**Ce que tu as appris :**

- Comprendre la haute disponibilité (99.9%+)
- Différencier ALB, NLB, CLB et choisir le bon
- Créer un Application Load Balancer multi-AZ
- Configurer des Target Groups avec health checks
- Créer une AMI personnalisée
- Définir un Launch Template
- Configurer un Auto Scaling Group (min/max/desired)
- Mettre en place des Scaling Policies (Target Tracking)
- Tester l'auto-scaling avec charge réelle
- Simuler des pannes et vérifier l'auto-healing
- Monitorer avec CloudWatch Metrics et Alarms
- Calculer et optimiser les coûts HA
- Déployer une architecture production-ready

**Compétences acquises :**

- [OK] Application Load Balancer (ALB)
- [OK] Target Groups et Health Checks
- [OK] Launch Templates et AMIs
- [OK] Auto Scaling Groups (ASG)
- [OK] Scaling Policies (Target Tracking, Step, Scheduled)
- [OK] Multi-AZ deployment
- [OK] CloudWatch Monitoring et Alarms
- [OK] SNS Notifications
- [OK] Cost optimization (Spot, Reserved, Scheduled)

**Architecture finale :**

```
Internet
   v
Application Load Balancer (Multi-AZ)
   v
Auto Scaling Group (2-10 instances)
├─ Instance 1 (AZ-A)
├─ Instance 2 (AZ-B)
└─ Instances 3-10 (scale dynamiquement)
   v
CloudWatch (monitoring)
   v
SNS (notifications)
```

**Disponibilité : 99.95%+**

**Coût : $40-65/mois** (vs $80+ sans Auto Scaling)

**Temps moyen de réalisation :** 4-5 heures

**Prochaine étape :** Exercice 7 - CloudFront + S3 - CDN Global ! [MONDE]

---