Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
| eadl:bloc4:fm4:td2 [2026/06/14 12:59] – jcheron | eadl:bloc4:fm4:td2 [2026/06/14 17:07] (Version actuelle) – [6. Correction – restriction du backend] jcheron | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | ====== TD2 – Sécurisation réseau AWS (VPC, Subnets, Security Groups, | + | ====== TD2 – Sécurisation réseau AWS (VPC, Security Groups, |
| ===== Objectifs ===== | ===== Objectifs ===== | ||
| - | * Comprendre | + | * Comprendre |
| - | * Identifier | + | * Identifier |
| - | * Mettre en place une segmentation réseau (public / privé) | + | * Mettre en place un point d' |
| - | * Contrôler les flux entre services (web, backend, base de données) | + | * Contrôler les flux réseau avec les Security Groups |
| - | * Appliquer le principe du moindre | + | * Appliquer le principe du moindre |
| ===== Contexte ===== | ===== Contexte ===== | ||
| - | Vous intervenez dans une startup. | + | Vous intervenez |
| - | Une application | + | L' |
| - | Architecture actuelle : | + | Le déploiement a été fait rapidement pour respecter un délai. |
| - | * un serveur web accessible depuis Internet | + | Résultat : |
| - | * un backend applicatif | + | |
| - | * une base de données | + | |
| - | Tout fonctionne, mais aucun design réseau n’a été pensé. | + | * l' |
| + | * mais toute l' | ||
| - | Un audit de sécurité | + | Un audit de sécurité |
| - | * isolation des composants | + | * le port applicatif du backend est ouvert à Internet |
| - | * suppression des accès inutiles | + | * le port de la base de données est ouvert à Internet |
| - | * contrôle strict des flux réseau | + | * aucun point d' |
| - | ===== Objectif technique ===== | + | Votre mission : transformer l' |
| - | Reconcevoir l’architecture réseau pour : | + | ===== Architecture cible ===== |
| - | * exposer uniquement le serveur web | + | L' |
| - | | + | |
| - | | + | |
| - | | + | |
| + | |||
| + | L' | ||
| + | |||
| + | | ||
| ===== Contraintes ===== | ===== Contraintes ===== | ||
| - | * Le serveur web doit rester accessible | + | * L' |
| - | * Le backend ne doit pas être accessible depuis Internet | + | * Le backend ne doit plus être accessible |
| - | * La base de données ne doit jamais | + | * La base de données ne doit être accessible que depuis le backend |
| - | * Chaque flux doit être justifié | + | * Tout le code est en Terraform |
| - | * Toute la configuration doit être faite avec Terraform | + | |
| - | ===== Infrastructure existante | + | ===== Pré-requis |
| - | Fichier : `network/ | + | * Terraform installé et configuré |
| + | * Credentials AWS valides | ||
| + | * Notions de base : VPC, subnet, Security Group | ||
| + | |||
| + | ===== Infrastructure de départ ===== | ||
| + | |||
| + | L' | ||
| + | |||
| + | Lire le code attentivement avant de l' | ||
| + | |||
| + | Fichier : `td2/network/ | ||
| <sxh js> | <sxh js> | ||
| provider " | provider " | ||
| - | region = " | + | region = " |
| } | } | ||
| + | # VPC principal | ||
| resource " | resource " | ||
| - | cidr_block = " | + | cidr_block |
| + | enable_dns_hostnames = true | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| } | } | ||
| - | resource "aws_subnet" "main" { | + | # Passerelle Internet |
| - | vpc_id | + | resource "aws_internet_gateway" "igw" { |
| - | | + | vpc_id = aws_vpc.main.id |
| + | |||
| + | | ||
| + | Name = "td2-igw" | ||
| + | } | ||
| } | } | ||
| - | resource "aws_instance" "web" { | + | # Subnet public – AZ a |
| - | | + | resource "aws_subnet" "public_a" { |
| - | | + | |
| - | | + | cidr_block |
| + | | ||
| + | | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| } | } | ||
| - | resource "aws_instance" "backend" { | + | # Subnet public – AZ b (requis par l' |
| - | | + | resource "aws_subnet" "public_b" { |
| - | | + | |
| - | | + | cidr_block |
| + | | ||
| + | | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| } | } | ||
| - | resource "aws_instance" "db" { | + | # Subnet privé – DB |
| - | | + | resource "aws_subnet" "private" { |
| - | | + | |
| - | | + | cidr_block |
| + | | ||
| + | |||
| + | | ||
| + | Name = " | ||
| + | } | ||
| } | } | ||
| - | resource " | + | # Table de routage publique |
| - | name = "all-open" | + | resource " |
| + | vpc_id = aws_vpc.main.id | ||
| + | |||
| + | route { | ||
| + | cidr_block = " | ||
| + | gateway_id = aws_internet_gateway.igw.id | ||
| + | } | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | resource " | ||
| + | subnet_id | ||
| + | route_table_id = aws_route_table.public.id | ||
| + | } | ||
| + | |||
| + | resource " | ||
| + | subnet_id | ||
| + | route_table_id = aws_route_table.public.id | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Fichier : `td2/ | ||
| + | <sxh js> | ||
| + | # Security Group backend – PROBLEME VOLONTAIRE | ||
| + | # Ce fichier sera modifié au cours du TD | ||
| + | resource " | ||
| + | name = "backend-sg" | ||
| vpc_id = aws_vpc.main.id | vpc_id = aws_vpc.main.id | ||
| ingress { | ingress { | ||
| + | description = "HTTP depuis Internet" | ||
| + | from_port | ||
| + | to_port | ||
| + | protocol | ||
| + | cidr_blocks = [" | ||
| + | } | ||
| + | |||
| + | egress { | ||
| from_port | from_port | ||
| to_port | to_port | ||
| protocol | protocol | ||
| + | cidr_blocks = [" | ||
| + | } | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | # Security Group DB – PROBLEME VOLONTAIRE | ||
| + | resource " | ||
| + | name = " | ||
| + | vpc_id = aws_vpc.main.id | ||
| + | |||
| + | ingress { | ||
| + | description = " | ||
| + | from_port | ||
| + | to_port | ||
| + | protocol | ||
| cidr_blocks = [" | cidr_blocks = [" | ||
| } | } | ||
| Ligne 97: | Ligne 191: | ||
| protocol | protocol | ||
| cidr_blocks = [" | cidr_blocks = [" | ||
| + | } | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| } | } | ||
| } | } | ||
| </ | </ | ||
| - | ===== Ressources ===== | + | Fichier : `td2/ |
| + | <sxh js> | ||
| + | resource " | ||
| + | ami | ||
| + | instance_type | ||
| + | subnet_id | ||
| + | vpc_security_group_ids | ||
| - | Commandes utiles : | + | user_data = << |
| + | # | ||
| + | yum install -y python3 | ||
| + | python3 -m http.server 80 & | ||
| + | EOF | ||
| - | Fichier : `commandes/ | + | tags = { |
| + | Name = " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | resource " | ||
| + | identifier | ||
| + | engine | ||
| + | engine_version | ||
| + | instance_class | ||
| + | allocated_storage | ||
| + | username | ||
| + | password | ||
| + | db_subnet_group_name | ||
| + | vpc_security_group_ids = [aws_security_group.db_sg.id] | ||
| + | skip_final_snapshot | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | resource " | ||
| + | name = " | ||
| + | subnet_ids = [aws_subnet.private.id, | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Commandes Terraform ===== | ||
| + | |||
| + | Fichier : `td2/commandes/ | ||
| <sxh bash> | <sxh bash> | ||
| + | # Initialiser le projet | ||
| terraform init | terraform init | ||
| + | |||
| + | # Vérifier le plan sans appliquer | ||
| terraform plan | terraform plan | ||
| + | |||
| + | # Appliquer la configuration | ||
| terraform apply | terraform apply | ||
| + | |||
| + | # Récupérer les outputs | ||
| + | terraform output | ||
| + | |||
| + | # Détruire l' | ||
| terraform destroy | terraform destroy | ||
| </ | </ | ||
| - | ===== 1. Analyse de l’existant | + | ===== 1. Lecture du code ===== |
| + | |||
| + | Lire les trois fichiers avant toute manipulation. | ||
| <WRAP round question> | <WRAP round question> | ||
| - | Identifier | + | Lister |
| - | Indiquer | + | Pour chaque ressource, indiquer |
| - | * les problèmes critiques | + | * son rôle |
| - | * les problèmes de conception | + | * le subnet dans lequel elle est placée |
| + | * les ports ouverts en entrée | ||
| </ | </ | ||
| - | |||
| - | ===== 2. Compréhension des flux ===== | ||
| <WRAP round question> | <WRAP round question> | ||
| - | Quels sont les flux nécessaires au fonctionnement | + | Pourquoi l'ALB nécessite-t-il deux subnets dans deux zones de disponibilité différentes |
| - | Lister précisément : | + | Quelle contrainte AWS cela reflète-t-il ? |
| + | </ | ||
| - | * Internet → Web | + | <WRAP round question> |
| - | * Web → Backend (port ?) | + | La base de données est une instance RDS et non une instance EC2. |
| - | * Backend → DB (port ?) | + | |
| - | Quels flux doivent être interdits | + | Quelle est la différence en termes de gestion et de sécurité |
| </ | </ | ||
| - | ===== 3. Mise en pratique – segmentation réseau | + | ===== 2. Identification des problèmes |
| <WRAP round todo> | <WRAP round todo> | ||
| + | Identifier dans `security_groups.tf` les deux règles les plus dangereuses. | ||
| - | Modifier l’infrastructure pour créer | + | Pour chaque règle |
| + | * expliquer ce qu' | ||
| + | * expliquer ce qu'un attaquant pourrait faire avec cet accès | ||
| + | </ | ||
| - | * 1 subnet public (web) | + | <WRAP round question> |
| - | * 1 subnet privé (backend + db) | + | Le mot de passe de la base de données est en clair dans le fichier Terraform. |
| + | |||
| + | Quel problème cela pose-t-il ? | ||
| + | Ce problème sera traité dans un TD ultérieur sur la gestion des secrets. | ||
| </ | </ | ||
| - | ===== 4. Mise en pratique – accès Internet | + | <WRAP round question> |
| + | La base de données RDS est placée dans un subnet group qui inclut le subnet `public_b`. | ||
| + | |||
| + | Est-ce un problème ? Pourquoi ? | ||
| + | </ | ||
| + | |||
| + | ===== 3. Déploiement de l' | ||
| <WRAP round todo> | <WRAP round todo> | ||
| + | Appliquer la configuration telle quelle : | ||
| - | Permettre : | + | terraform apply |
| - | * accès Internet au serveur web | + | Relever les outputs suivants : |
| - | * accès sortant pour le backend | + | * IP publique de l' |
| + | * endpoint de la base RDS | ||
| + | </ | ||
| - | Ajouter les composants nécessaires. | + | Fichier : `td2/ |
| + | <sxh js> | ||
| + | output " | ||
| + | value = aws_instance.backend.public_ip | ||
| + | description = "IP publique du backend" | ||
| + | } | ||
| + | output " | ||
| + | value = aws_db_instance.db.endpoint | ||
| + | description = " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <WRAP round todo> | ||
| + | Tester l' | ||
| + | |||
| + | curl http://< | ||
| + | |||
| + | Tenter une connexion à la base de données depuis votre poste : | ||
| + | |||
| + | psql -h < | ||
| + | |||
| + | Noter le résultat de chaque test. | ||
| </ | </ | ||
| <WRAP round question> | <WRAP round question> | ||
| - | Pourquoi le backend | + | Le backend |
| + | |||
| + | La connexion à la base de données est-elle possible depuis votre poste ? | ||
| + | |||
| + | Pourquoi ce comportement est-il problématique dans un contexte de production | ||
| </ | </ | ||
| - | ===== 5. Mise en pratique – Security Groups | + | ===== 4. Mise en place de l' |
| <WRAP round todo> | <WRAP round todo> | ||
| + | Créer le fichier suivant sans modifier les Security Groups existants. | ||
| + | </ | ||
| - | Créer 3 Security Groups | + | Fichier |
| + | <sxh js> | ||
| + | # Security Group de l' | ||
| + | resource " | ||
| + | name = " | ||
| + | vpc_id = aws_vpc.main.id | ||
| - | | + | |
| - | * backend-sg | + | |
| - | | + | from_port |
| + | to_port | ||
| + | protocol | ||
| + | cidr_blocks = [" | ||
| + | | ||
| - | Définir les règles suivantes : | + | egress { |
| + | from_port | ||
| + | to_port | ||
| + | protocol | ||
| + | cidr_blocks = [" | ||
| + | } | ||
| - | | + | |
| - | - HTTP depuis Internet | + | |
| - | | + | |
| - | - accessible uniquement depuis web | + | } |
| - | * db : | + | |
| - | - accessible uniquement depuis backend | + | |
| - | </ | + | # Application Load Balancer |
| + | resource " | ||
| + | name = " | ||
| + | internal | ||
| + | load_balancer_type = " | ||
| + | security_groups | ||
| + | subnets | ||
| - | ===== 6. Erreur volontaire ===== | + | tags = { |
| + | Name = " | ||
| + | } | ||
| + | } | ||
| - | Un développeur propose la règle suivante pour le backend | + | # Target Group |
| + | resource " | ||
| + | name = " | ||
| + | port = 80 | ||
| + | protocol = " | ||
| + | vpc_id | ||
| - | | + | |
| + | path = "/" | ||
| + | healthy_threshold | ||
| + | unhealthy_threshold = 2 | ||
| + | interval | ||
| + | } | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | # Attachement du backend au Target Group | ||
| + | resource " | ||
| + | target_group_arn = aws_lb_target_group.backend.arn | ||
| + | target_id | ||
| + | | ||
| + | } | ||
| + | |||
| + | # Listener HTTP | ||
| + | resource " | ||
| + | load_balancer_arn = aws_lb.main.arn | ||
| + | port = 80 | ||
| + | protocol | ||
| + | |||
| + | default_action { | ||
| + | type = " | ||
| + | target_group_arn = aws_lb_target_group.backend.arn | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <WRAP round todo> | ||
| + | Ajouter l' | ||
| + | |||
| + | output " | ||
| + | value = aws_lb.main.dns_name | ||
| + | description = "DNS public de l' | ||
| + | } | ||
| + | |||
| + | Appliquer : | ||
| + | |||
| + | terraform apply | ||
| + | |||
| + | Tester l' | ||
| + | |||
| + | curl http://< | ||
| + | |||
| + | Tester également l' | ||
| + | |||
| + | curl http://< | ||
| + | </WRAP> | ||
| <WRAP round question> | <WRAP round question> | ||
| - | Pourquoi cette règle est dangereuse | + | Les deux accès fonctionnent-ils |
| - | Dans quel cas peut-elle sembler fonctionner correctement | + | Qu'est-ce que cela démontre sur l' |
| + | |||
| + | L'ALB est-il suffisant seul pour sécuriser le backend | ||
| </ | </ | ||
| - | ===== 7. Apparition d’un problème | + | ===== 5. Erreur courante – le backend reste exposé |
| - | Après mise en place des règles : | + | L'ALB est en place mais le Security Group du backend n'a pas été modifié. |
| - | * le site web fonctionne | + | Le port 80 du backend est toujours ouvert sur `0.0.0.0/ |
| - | * mais l’application ne répond plus correctement | + | |
| <WRAP round question> | <WRAP round question> | ||
| - | Que vérifier en priorité | + | Pourquoi ajouter un ALB ne suffit-il pas à protéger le backend |
| - | * Security Groups | + | Quel composant contrôle réellement les accès réseau sur une instance AWS ? |
| - | * ports ? | + | </ |
| - | * flux autorisés ? | + | |
| + | ===== 6. Correction – restriction du backend ===== | ||
| + | |||
| + | <WRAP round todo> | ||
| + | Modifier `security_groups.tf`. | ||
| + | |||
| + | Remplacer la règle ingress du Security Group `backend_sg` : | ||
| + | * supprimer l' | ||
| + | * autoriser uniquement le trafic depuis le Security Group de l'ALB | ||
| </ | </ | ||
| - | ===== 8. Correction | + | Fichier : `td2/ |
| + | <sxh js> | ||
| + | resource " | ||
| + | name = " | ||
| + | vpc_id | ||
| + | |||
| + | ingress { | ||
| + | description | ||
| + | from_port | ||
| + | to_port | ||
| + | protocol | ||
| + | security_groups = [aws_security_group.alb_sg.id] | ||
| + | } | ||
| + | |||
| + | egress { | ||
| + | from_port | ||
| + | to_port | ||
| + | protocol | ||
| + | cidr_blocks = [" | ||
| + | } | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | resource " | ||
| + | name = " | ||
| + | vpc_id = aws_vpc.main.id | ||
| + | |||
| + | ingress { | ||
| + | description | ||
| + | from_port | ||
| + | to_port | ||
| + | protocol | ||
| + | security_groups = [aws_security_group.backend_sg.id] | ||
| + | } | ||
| + | |||
| + | egress { | ||
| + | from_port | ||
| + | to_port | ||
| + | protocol | ||
| + | cidr_blocks = [" | ||
| + | } | ||
| + | |||
| + | tags = { | ||
| + | Name = " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| <WRAP round todo> | <WRAP round todo> | ||
| + | Appliquer les modifications : | ||
| + | |||
| + | terraform apply | ||
| - | Corriger | + | Tester |
| - | | + | |
| - | | + | |
| + | # Direct – doit échouer | ||
| + | curl http://< | ||
| </ | </ | ||
| - | ===== 9. Extension ===== | + | <WRAP round question> |
| + | L' | ||
| - | <WRAP round todo> | + | L' |
| - | Ajouter : | + | Que se passe-t-il si le Health Check de l'ALB échoue ? |
| + | Comment vérifier l' | ||
| + | </ | ||
| - | * un NAT Gateway | + | ===== 7. Problème potentiel – Health Check ===== |
| - | * permettre au backend de faire des mises à jour sans être exposé | + | |
| + | Après modification des Security Groups, l'ALB peut afficher le backend comme " | ||
| + | |||
| + | <WRAP round question> | ||
| + | Expliquer ce qu'est un Health Check d'ALB. | ||
| + | |||
| + | Quel flux réseau le Health Check génère-t-il ? | ||
| + | |||
| + | Depuis quelle source arrive ce flux sur le backend ? | ||
| </ | </ | ||
| <WRAP round question> | <WRAP round question> | ||
| - | Quelle différence entre : | + | Si le backend est " |
| - | * Internet Gateway | + | Le service devient indisponible même si le backend fonctionne. |
| - | * NAT Gateway | + | |
| + | Quelle règle dans le Security Group du backend pourrait causer ce blocage | ||
| </ | </ | ||
| - | ===== 10. Bonnes pratiques | + | <WRAP round todo> |
| + | Vérifier dans la console AWS : | ||
| + | * aller dans EC2 > Target Groups | ||
| + | * vérifier le statut de l' | ||
| + | * lire le message d' | ||
| + | </ | ||
| + | |||
| + | ===== 8. Diagnostic et correction | ||
| + | |||
| + | <WRAP round todo> | ||
| + | Si le Health Check échoue, identifier la cause : | ||
| + | |||
| + | * le port 80 est-il bien ouvert depuis le Security Group de l'ALB ? | ||
| + | * le service python3 est-il démarré sur l' | ||
| + | * la règle egress de l'ALB permet-elle les réponses ? | ||
| + | |||
| + | Corriger la règle manquante et réappliquer. | ||
| + | </ | ||
| + | |||
| + | ===== 9. Vérification finale ===== | ||
| + | |||
| + | <WRAP round todo> | ||
| + | Réaliser les tests suivants et noter les résultats dans un tableau : | ||
| + | |||
| + | * accès HTTP via l'ALB → attendu : 200 | ||
| + | * accès HTTP direct au backend → attendu : timeout ou refus | ||
| + | * connexion PostgreSQL depuis votre poste → attendu : timeout ou refus | ||
| + | * connexion PostgreSQL depuis le backend → attendu : possible | ||
| + | </ | ||
| <WRAP round question> | <WRAP round question> | ||
| - | Pourquoi utiliser : | + | Comment vérifier qu'un flux est bien bloqué et non juste lent ? |
| - | * un Security Group par service ? | + | Quelle différence entre un timeout et un Connection refused en termes de Security Group ? |
| - | * des règles basées sur des Security Groups plutôt que des IP ? | + | |
| </ | </ | ||
| - | ===== Challenge final ===== | + | ===== 10. Extension – déplacement du backend en subnet privé |
| - | Objectif : | + | Le backend a une IP publique car il est dans un subnet public. |
| - | * Web accessible depuis Internet (port 80) | + | Ce n'est pas nécessaire si l'ALB gère tout le trafic entrant. |
| - | * Backend inaccessible depuis Internet | + | |
| - | * DB inaccessible depuis Internet | + | |
| - | * Backend accessible uniquement depuis Web | + | |
| - | * DB accessible uniquement depuis Backend | + | |
| <WRAP round todo> | <WRAP round todo> | ||
| + | Modifier `instances.tf` pour déplacer le backend dans le subnet privé : | ||
| - | Implémenter l’architecture complète. | + | subnet_id = aws_subnet.private.id |
| - | Vérifier que : | + | Supprimer également le `map_public_ip_on_launch` implicite. |
| - | * aucun flux inutile | + | Appliquer et vérifier que l'ALB continue de fonctionner. |
| - | * chaque règle est justifiée | + | </ |
| + | |||
| + | <WRAP round question> | ||
| + | Le backend | ||
| + | |||
| + | Est-il encore accessible depuis Internet ? | ||
| + | |||
| + | Comment l'ALB peut-il atteindre une instance dans un subnet privé ? | ||
| + | Quel composant réseau manque pour que le backend puisse faire des appels sortants (mises à jour, appels API externes) ? | ||
| </ | </ | ||
| - | ===== Bonus ===== | + | ===== Challenge final ===== |
| + | |||
| + | Objectif : valider l' | ||
| <WRAP round todo> | <WRAP round todo> | ||
| + | Dessiner l' | ||
| + | * les subnets (public_a, public_b, private) | ||
| + | * les composants dans chaque subnet | ||
| + | * les Security Groups et leurs règles | ||
| + | * les flux autorisés avec les ports | ||
| + | </ | ||
| - | Ajouter | + | <WRAP round todo> |
| + | Répondre aux questions suivantes par écrit | ||
| - | * un second serveur web | + | * Quel composant est le seul point d' |
| - | * un Load Balancer | + | * Quelles ressources ne sont plus accessibles directement depuis Internet ? |
| + | * Quel principe de sécurité est appliqué sur chaque Security Group ? | ||
| + | * Que se passe-t-il si l'ALB est supprimé ? L' | ||
| + | </ | ||
| + | ===== Bonus ===== | ||
| + | |||
| + | <WRAP round todo> | ||
| + | Ajouter une seconde instance backend dans `public_b` : | ||
| + | |||
| + | resource " | ||
| + | ami = " | ||
| + | instance_type | ||
| + | subnet_id | ||
| + | vpc_security_group_ids = [aws_security_group.backend_sg.id] | ||
| + | ... | ||
| + | } | ||
| + | |||
| + | Attacher cette instance au même Target Group. | ||
| </ | </ | ||
| <WRAP round question> | <WRAP round question> | ||
| - | Pourquoi | + | Quels sont les avantages d' |
| + | |||
| + | Répondre selon deux axes : | ||
| + | * disponibilité : que se passe-t-il si une instance tombe ? | ||
| + | * sécurité | ||
| </ | </ | ||