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 | |||
| eadl:bloc4:fm4:td3 [2026/06/24 08:09] – [3. Declaration des variables] jcheron | eadl:bloc4:fm4:td3 [2026/06/24 08:10] (Version actuelle) – jcheron | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | ====== TD3 – Gestion des secrets, chiffrement et traçabilité AWS ====== | ||
| - | |||
| - | ===== Objectifs ===== | ||
| - | |||
| - | * Supprimer les secrets en clair dans une infrastructure Terraform | ||
| - | * Utiliser AWS Secrets Manager pour stocker des identifiants sensibles | ||
| - | * Activer le chiffrement des données au repos sur RDS et S3 | ||
| - | * Comprendre la différence entre chiffrement au repos et en transit | ||
| - | * Mettre en place une traçabilité avec CloudTrail | ||
| - | * Identifier une action suspecte via les logs | ||
| - | |||
| - | ===== Contexte ===== | ||
| - | |||
| - | Suite au TD2, l' | ||
| - | |||
| - | Le VPC est segmenté, l'ALB filtre le trafic entrant, les Security Groups isolent chaque couche. | ||
| - | |||
| - | Un nouvel audit de sécurité interne est réalisé. | ||
| - | |||
| - | Trois failles critiques sont identifiées malgré les corrections du TD2 : | ||
| - | |||
| - | * le mot de passe de la base de données est stocké en clair dans `instances.tf` | ||
| - | * la base de données RDS n'est pas chiffrée au repos | ||
| - | * aucune trace des actions réalisées sur le compte AWS n'est conservée | ||
| - | |||
| - | Ces trois points constituent des non-conformités bloquantes pour toute certification de sécurité (ISO 27001, SOC 2, RGPD). | ||
| - | |||
| - | Votre mission est de corriger ces trois failles en prolongeant l' | ||
| - | |||
| - | ===== Pré-requis ===== | ||
| - | |||
| - | * Projet Terraform du TD2 déployé et fonctionnel | ||
| - | * ALB opérationnel, | ||
| - | * Accès AWS avec droits suffisants : IAM, Secrets Manager, S3, RDS, CloudTrail | ||
| - | * Terraform en version 1.5 ou supérieure | ||
| - | |||
| - | ===== Structure du projet ===== | ||
| - | |||
| - | Le TD3 s' | ||
| - | |||
| - | <sxh bash; | ||
| - | td3/ | ||
| - | ├── main.tf | ||
| - | ├── variables.tf | ||
| - | ├── outputs.tf | ||
| - | ├── providers.tf | ||
| - | └── modules/ | ||
| - | ├── secrets/ | ||
| - | │ | ||
| - | ├── database/ | ||
| - | │ | ||
| - | ├── storage/ | ||
| - | │ | ||
| - | └── logging/ | ||
| - | └── main.tf | ||
| - | </ | ||
| - | |||
| - | Le dossier `td2/` n'est pas modifié directement. | ||
| - | |||
| - | Les ressources existantes du TD2 sont récupérées via des data sources Terraform. | ||
| - | |||
| - | <WRAP round question> | ||
| - | Pourquoi utilise-t-on des data sources plutôt que de copier les ressources du TD2 dans TD3 ? | ||
| - | |||
| - | Que se passerait-il si on déclarait une deuxième fois la même ressource avec le même nom ? | ||
| - | </ | ||
| - | |||
| - | ===== 1. Analyse de l' | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Ouvrir le fichier `td2/ | ||
| - | |||
| - | Localiser la ressource `aws_db_instance.db`. | ||
| - | </ | ||
| - | |||
| - | <WRAP round question> | ||
| - | Relever les trois problèmes de sécurité présents dans cette ressource. | ||
| - | |||
| - | Pour chaque problème, indiquer : | ||
| - | * ce qui est en cause dans le code | ||
| - | * ce qu'un attaquant ou un développeur malveillant pourrait faire | ||
| - | * si ce problème est visible dans Git | ||
| - | </ | ||
| - | |||
| - | <WRAP round question> | ||
| - | Le fichier `instances.tf` est versionné dans Git. | ||
| - | |||
| - | Un développeur a poussé ce fichier il y a trois mois sur le dépôt de l' | ||
| - | |||
| - | Le mot de passe a été changé depuis, mais il reste dans l' | ||
| - | |||
| - | Comment retrouver ce mot de passe dans l' | ||
| - | |||
| - | Pourquoi changer le mot de passe ne suffit-il pas si le fichier a déjà été commité ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round question> | ||
| - | La ressource `aws_db_instance.db` dans le TD2 ne contient pas le paramètre `storage_encrypted`. | ||
| - | |||
| - | Quelle est la valeur par défaut de ce paramètre dans AWS ? | ||
| - | |||
| - | Que signifie concrètement une base non chiffrée au repos ? | ||
| - | </ | ||
| - | |||
| - | ===== 2. Declaration des providers ===== | ||
| - | |||
| - | Le module `storage` utilisera le provider `random` pour générer des suffixes uniques sur les noms de buckets S3. | ||
| - | |||
| - | Les noms de buckets S3 sont globaux sur AWS : deux comptes ne peuvent pas avoir le même nom. | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Créer le fichier de déclaration des providers. | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh js> | ||
| - | terraform { | ||
| - | required_providers { | ||
| - | aws = { | ||
| - | source | ||
| - | version = "~> 5.0" | ||
| - | } | ||
| - | random = { | ||
| - | source | ||
| - | version = "~> 3.0" | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | |||
| - | provider " | ||
| - | region = " | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round question> | ||
| - | Pourquoi faut-il déclarer explicitement le provider `random` alors qu'il ne communique pas avec AWS ? | ||
| - | |||
| - | Que se passe-t-il si on l' | ||
| - | </ | ||
| - | |||
| ====== TD3 – Gestion des secrets, chiffrement et traçabilité AWS ====== | ====== TD3 – Gestion des secrets, chiffrement et traçabilité AWS ====== | ||
| Ligne 971: | Ligne 831: | ||
| <WRAP round question> | <WRAP round question> | ||
| Après une rotation automatique, | Après une rotation automatique, | ||
| - | |||
| - | Si l' | ||
| - | |||
| - | Comment une application bien conçue doit-elle récupérer les secrets pour éviter ce problème ? | ||
| - | </ | ||
| - | |||
| - | ===== 4. Recuperation des ressources existantes du TD2 ===== | ||
| - | |||
| - | Plutôt que de recréer les ressources, on les référence via des data sources. | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Créer le fichier principal du TD3. | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | # Recuperation du VPC existant du TD2 | ||
| - | data " | ||
| - | filter { | ||
| - | name = " | ||
| - | values = [" | ||
| - | } | ||
| - | } | ||
| - | |||
| - | # Recuperation du Security Group du backend TD2 | ||
| - | data " | ||
| - | filter { | ||
| - | name = " | ||
| - | values = [" | ||
| - | } | ||
| - | vpc_id = data.aws_vpc.td2.id | ||
| - | } | ||
| - | |||
| - | # Recuperation du subnet group RDS existant | ||
| - | data " | ||
| - | name = " | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Une data source ne crée rien dans AWS. | ||
| - | |||
| - | Que fait Terraform quand il rencontre un bloc `data` lors d'un `terraform plan` ? | ||
| - | |||
| - | Que se passe-t-il si la ressource référencée n' | ||
| - | </ | ||
| - | |||
| - | ===== 5. Module secrets ===== | ||
| - | |||
| - | Objectif : stocker le mot de passe dans AWS Secrets Manager, pas dans le code. | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Créer le module de gestion des secrets. | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | variable " | ||
| - | type = string | ||
| - | sensitive = true | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | name = " | ||
| - | description | ||
| - | recovery_window_in_days = 0 | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | secret_id = aws_secretsmanager_secret.db_credentials.id | ||
| - | |||
| - | secret_string = jsonencode({ | ||
| - | username = " | ||
| - | password = var.db_password | ||
| - | }) | ||
| - | } | ||
| - | |||
| - | output " | ||
| - | description = "ARN du secret a transmettre au module database" | ||
| - | value = aws_secretsmanager_secret.db_credentials.arn | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Le secret est stocké au format JSON avec deux champs : `username` et `password`. | ||
| - | |||
| - | Pourquoi utilise-t-on un objet JSON plutôt qu'une simple chaîne de caractères ? | ||
| - | |||
| - | Quel avantage si on doit ajouter le port ou le nom de la base plus tard ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Le paramètre `recovery_window_in_days = 0` supprime le secret immédiatement lors d'un `terraform destroy`. | ||
| - | |||
| - | Quelle est la valeur par défaut d'AWS pour ce paramètre ? | ||
| - | |||
| - | Pourquoi cette valeur par défaut existe-t-elle en production ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Ajouter l' | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | module " | ||
| - | source | ||
| - | db_password = var.db_initial_password | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== 6. Probleme volontaire : ordre d' | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Avant d' | ||
| - | |||
| - | <sxh hcl> | ||
| - | data " | ||
| - | secret_id = " | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Ajouter ce bloc temporairement dans `main.tf` et lancer : | ||
| - | |||
| - | <sxh bash> | ||
| - | terraform plan | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Que se passe-t-il lors du plan ? | ||
| - | |||
| - | Terraform signale-t-il une erreur, et si oui, laquelle ? | ||
| - | |||
| - | Pourquoi Terraform ne peut-il pas garantir que le secret existe au moment où la data source est évaluée ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Quelle est la différence fondamentale entre un bloc `resource` et un bloc `data` dans le cycle d' | ||
| - | |||
| - | Lequel est évalué lors de la phase de lecture, avant toute création ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Supprimer ce bloc temporaire avant de continuer. | ||
| - | </ | ||
| - | |||
| - | ===== 7. Module database ===== | ||
| - | |||
| - | Objectif : remplacer la ressource RDS du TD2 par une version sécurisée. | ||
| - | |||
| - | La dépendance entre le secret et la base est gérée implicitement via le passage de l'ARN en variable. | ||
| - | |||
| - | Terraform comprend qu'il doit créer le secret avant de lire son contenu car la valeur vient d'un output du module `secrets`. | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Créer le module base de données. | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | variable " | ||
| - | type = string | ||
| - | description = "ARN du secret contenant les identifiants de la base" | ||
| - | } | ||
| - | |||
| - | variable " | ||
| - | type = string | ||
| - | description = "Nom du subnet group RDS existant" | ||
| - | } | ||
| - | |||
| - | variable " | ||
| - | type = list(string) | ||
| - | description = "Liste des Security Group IDs autorises a acceder a la base" | ||
| - | } | ||
| - | |||
| - | data " | ||
| - | secret_id = var.secret_arn | ||
| - | } | ||
| - | |||
| - | locals { | ||
| - | db_creds = jsondecode(data.aws_secretsmanager_secret_version.db_credentials.secret_string) | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | identifier | ||
| - | engine | ||
| - | engine_version | ||
| - | instance_class | ||
| - | allocated_storage = 20 | ||
| - | |||
| - | db_name | ||
| - | username = local.db_creds[" | ||
| - | password = local.db_creds[" | ||
| - | |||
| - | db_subnet_group_name | ||
| - | vpc_security_group_ids = var.vpc_security_group_ids | ||
| - | |||
| - | storage_encrypted | ||
| - | skip_final_snapshot = true | ||
| - | |||
| - | tags = { | ||
| - | Name = " | ||
| - | } | ||
| - | } | ||
| - | |||
| - | output " | ||
| - | description = " | ||
| - | value = aws_db_instance.main.endpoint | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Ajouter l' | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | module " | ||
| - | source | ||
| - | secret_arn | ||
| - | |||
| - | db_subnet_group_name | ||
| - | vpc_security_group_ids = [data.aws_security_group.backend.id] | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | La valeur `module.secrets.secret_arn` est transmise en variable au module database. | ||
| - | |||
| - | Terraform en déduit-il automatiquement que le module `database` dépend du module `secrets` ? | ||
| - | |||
| - | Dans quel cas faudrait-il ajouter un `depends_on` explicite malgré tout ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Le paramètre `storage_encrypted = true` a été ajouté. | ||
| - | |||
| - | Que protège exactement ce chiffrement ? | ||
| - | |||
| - | Ce chiffrement protège-t-il les données qui transitent entre le backend et la base de données ? | ||
| - | |||
| - | Quel mécanisme complémentaire protège les données en transit vers RDS ? | ||
| - | </ | ||
| - | |||
| - | ===== 8. Module storage ===== | ||
| - | |||
| - | Objectif : créer un bucket S3 avec chiffrement et blocage des accès publics. | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Créer le module de stockage. | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | resource " | ||
| - | byte_length = 4 | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | bucket = " | ||
| - | |||
| - | tags = { | ||
| - | Name = " | ||
| - | } | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | bucket = aws_s3_bucket.secure_data.id | ||
| - | |||
| - | rule { | ||
| - | apply_server_side_encryption_by_default { | ||
| - | sse_algorithm = " | ||
| - | } | ||
| - | bucket_key_enabled = true | ||
| - | } | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | bucket = aws_s3_bucket.secure_data.id | ||
| - | |||
| - | block_public_acls | ||
| - | block_public_policy | ||
| - | ignore_public_acls | ||
| - | restrict_public_buckets = true | ||
| - | } | ||
| - | |||
| - | output " | ||
| - | description = "Nom du bucket S3 securise" | ||
| - | value = aws_s3_bucket.secure_data.id | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Ajouter l' | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | module " | ||
| - | source = " | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | La configuration `apply_server_side_encryption_by_default` est activée. | ||
| - | |||
| - | Que se passe-t-il si un développeur uploade un fichier sans spécifier de chiffrement dans son appel SDK ou CLI ? | ||
| - | |||
| - | La configuration par défaut s' | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Les quatre paramètres `block_public_acls`, | ||
| - | |||
| - | Les Security Groups du TD2 contrôlent déjà le trafic réseau vers les instances. | ||
| - | |||
| - | Pourquoi bloquer également les accès publics au niveau du bucket S3 ? | ||
| - | |||
| - | S3 est-il soumis aux Security Groups ? | ||
| - | </ | ||
| - | |||
| - | ===== 9. Module logging ===== | ||
| - | |||
| - | Objectif : tracer toutes les actions réalisées sur le compte AWS via CloudTrail. | ||
| - | |||
| - | CloudTrail écrit ses logs dans un bucket S3 dédié. | ||
| - | |||
| - | AWS exige une policy bucket explicite pour autoriser CloudTrail à écrire. | ||
| - | |||
| - | Sans cette policy, la ressource `aws_cloudtrail` échoue au déploiement. | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Créer le module de logging. | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | data " | ||
| - | |||
| - | resource " | ||
| - | bucket = " | ||
| - | |||
| - | tags = { | ||
| - | Name = " | ||
| - | } | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | bucket = aws_s3_bucket.cloudtrail_logs.id | ||
| - | |||
| - | block_public_acls | ||
| - | block_public_policy | ||
| - | ignore_public_acls | ||
| - | restrict_public_buckets = true | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | bucket = aws_s3_bucket.cloudtrail_logs.id | ||
| - | |||
| - | policy = jsonencode({ | ||
| - | Version = " | ||
| - | Statement = [ | ||
| - | { | ||
| - | Sid = " | ||
| - | Effect = " | ||
| - | Principal = { | ||
| - | Service = " | ||
| - | } | ||
| - | Action | ||
| - | Resource = aws_s3_bucket.cloudtrail_logs.arn | ||
| - | }, | ||
| - | { | ||
| - | Sid = " | ||
| - | Effect = " | ||
| - | Principal = { | ||
| - | Service = " | ||
| - | } | ||
| - | Action | ||
| - | Resource = " | ||
| - | Condition = { | ||
| - | StringEquals = { | ||
| - | " | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | ] | ||
| - | }) | ||
| - | |||
| - | depends_on = [aws_s3_bucket_public_access_block.cloudtrail_logs] | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | name = " | ||
| - | s3_bucket_name | ||
| - | include_global_service_events = true | ||
| - | is_multi_region_trail | ||
| - | enable_log_file_validation | ||
| - | |||
| - | tags = { | ||
| - | Name = " | ||
| - | } | ||
| - | |||
| - | depends_on = [aws_s3_bucket_policy.cloudtrail_logs] | ||
| - | } | ||
| - | |||
| - | output " | ||
| - | description = "Nom du trail CloudTrail actif" | ||
| - | value = aws_cloudtrail.main.name | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Ajouter l' | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | module " | ||
| - | source = " | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | La policy S3 contient deux instructions distinctes : `AWSCloudTrailAclCheck` et `AWSCloudTrailWrite`. | ||
| - | |||
| - | Pourquoi CloudTrail a-t-il besoin de lire l'ACL du bucket avant d'y écrire ? | ||
| - | |||
| - | Que se serait-il passé si on avait appliqué `aws_cloudtrail` sans cette policy ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Le paramètre `enable_log_file_validation = true` est activé. | ||
| - | |||
| - | Que génère AWS pour permettre cette validation ? | ||
| - | |||
| - | Comment un administrateur peut-il vérifier qu'un fichier de log n'a pas été modifié ou supprimé ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | CloudTrail enregistre les appels API réalisés sur le compte AWS. | ||
| - | |||
| - | Les modifications de Security Groups réalisées dans le TD2 via Terraform auraient-elles été enregistrées si CloudTrail avait été actif à ce moment ? | ||
| - | |||
| - | Quelle différence entre CloudTrail et VPC Flow Logs ? | ||
| - | </ | ||
| - | |||
| - | ===== 10. Fichier outputs global ===== | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Créer le fichier d' | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | output " | ||
| - | description = " | ||
| - | value = module.database.db_endpoint | ||
| - | } | ||
| - | |||
| - | output " | ||
| - | description = "Nom du bucket S3 securise" | ||
| - | value = module.storage.bucket_name | ||
| - | } | ||
| - | |||
| - | output " | ||
| - | description = "Nom du trail CloudTrail actif" | ||
| - | value = module.logging.cloudtrail_name | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== 11. Deploiement complet ===== | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Initialiser le projet et vérifier le plan avant d' | ||
| - | |||
| - | <sxh bash> | ||
| - | cd td3/ | ||
| - | terraform init | ||
| - | terraform plan | ||
| - | terraform apply | ||
| - | </ | ||
| - | |||
| - | Relever les outputs après application. | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Lors du `terraform plan`, combien de ressources sont listées comme a créer ? | ||
| - | |||
| - | Les data sources vers le TD2 apparaissent-elles dans le plan ? | ||
| - | |||
| - | Que se passe-t-il si le VPC `td2-vpc` n' | ||
| - | </ | ||
| - | |||
| - | ===== 12. Simulation d'un incident et lecture des logs ===== | ||
| - | |||
| - | Objectif : vérifier que CloudTrail trace bien les actions réalisées sur le compte. | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Modifier temporairement un Security Group du TD2 via Terraform. | ||
| - | |||
| - | Par exemple, rouvrir le port 5432 sur `0.0.0.0/0` dans `td2/ | ||
| - | |||
| - | Appliquer ce changement : | ||
| - | |||
| - | <sxh bash> | ||
| - | cd td2/ | ||
| - | terraform apply | ||
| - | </ | ||
| - | |||
| - | Attendre deux minutes. | ||
| - | |||
| - | Se connecter à la console AWS et naviguer vers : | ||
| - | |||
| - | CloudTrail > Event history | ||
| - | |||
| - | Filtrer par nom d' | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | L' | ||
| - | |||
| - | Quelles informations sont disponibles dans le détail de l' | ||
| - | * quel utilisateur ou rôle IAM a réalisé l' | ||
| - | * depuis quelle adresse IP ? | ||
| - | * à quelle heure exactement ? | ||
| - | * quelle ressource a été modifiée ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Un Security Group du TD2 a été ouvert sur Internet par erreur un vendredi soir. | ||
| - | |||
| - | L' | ||
| - | |||
| - | Comment CloudTrail permet-il de répondre aux questions suivantes sans CloudTrail et avec CloudTrail : | ||
| - | * depuis combien de temps la faille est-elle ouverte ? | ||
| - | * qui a fait la modification ? | ||
| - | * s' | ||
| - | </ | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Remettre le Security Group du TD2 dans son état sécurisé après l' | ||
| - | |||
| - | <sxh bash> | ||
| - | cd td2/ | ||
| - | terraform apply | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Pourquoi est-il important de conserver les logs CloudTrail pendant au moins un an ? | ||
| - | |||
| - | Quelles obligations légales ou réglementaires peuvent imposer cette durée en France et en Europe ? | ||
| - | </ | ||
| - | |||
| - | ===== 13. Vérification globale ===== | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Vérifier les points suivants avant de passer au challenge : | ||
| - | |||
| - | * aucun mot de passe n' | ||
| - | * le fichier `terraform.tfvars` est présent dans `.gitignore` | ||
| - | * le secret est visible dans la console AWS Secrets Manager sous le nom `td3/ | ||
| - | * la ressource `aws_db_instance` dans le module database contient `storage_encrypted = true` | ||
| - | * le bucket S3 applicatif a le chiffrement AES256 actif | ||
| - | * le bucket S3 applicatif a les quatre blocages d' | ||
| - | * CloudTrail est actif dans la console AWS | ||
| - | * la validation des fichiers de log est activée sur le trail | ||
| - | </ | ||
| - | |||
| - | ===== Challenge final ===== | ||
| - | |||
| - | **Axe secrets** | ||
| - | |||
| - | <WRAP round help> | ||
| - | Où est physiquement stocké le mot de passe de la base de données maintenant ? | ||
| - | |||
| - | Comparer avec la situation du TD2 : qui pouvait y accéder avant, qui peut y accéder maintenant ? | ||
| - | |||
| - | Comment restreindre l' | ||
| - | </ | ||
| - | |||
| - | **Axe chiffrement** | ||
| - | |||
| - | <WRAP round help> | ||
| - | Le paramètre `storage_encrypted = true` sur RDS protège-t-il les données pendant leur transfert entre le backend et la base ? | ||
| - | |||
| - | Quel mécanisme complémentaire faut-il activer pour protéger les données en transit ? | ||
| - | |||
| - | Dans quel cas le chiffrement AES256 de S3 ne suffit-il pas a garantir la confidentialite des données ? | ||
| - | </ | ||
| - | |||
| - | **Axe traçabilité** | ||
| - | |||
| - | <WRAP round help> | ||
| - | Un stagiaire supprime accidentellement la ressource CloudTrail via `terraform destroy` sur le module logging. | ||
| - | |||
| - | Quelles sont les conséquences immédiates pour la traçabilité du compte ? | ||
| - | |||
| - | Comment aurait-on pu protéger cette ressource contre une suppression accidentelle ? | ||
| - | |||
| - | Chercher le paramètre Terraform qui permet de protéger une ressource contre la destruction. | ||
| - | </ | ||
| - | |||
| - | **Axe architecture** | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Produire un schéma de l' | ||
| - | |||
| - | Le schéma doit inclure : | ||
| - | * les composants du TD2 : ALB, backend, Security Groups, subnets | ||
| - | * les ajouts du TD3 : Secrets Manager, RDS chiffré, S3 applicatif, CloudTrail et son bucket | ||
| - | * les flux de données entre chaque composant avec les ports concernés | ||
| - | * une légende distinguant les flux chiffrés et les flux non chiffrés | ||
| - | </ | ||
| - | |||
| - | ===== Bonus ===== | ||
| - | |||
| - | **Rotation automatique des secrets** | ||
| - | |||
| - | <WRAP round todo> | ||
| - | Rechercher dans la documentation AWS comment activer la rotation automatique d'un secret Secrets Manager pour une base PostgreSQL. | ||
| - | |||
| - | Identifier l'ARN de la Lambda de rotation fournie par AWS pour PostgreSQL dans la région `eu-west-3`. | ||
| - | |||
| - | Ajouter la rotation dans le module secrets. | ||
| - | </ | ||
| - | |||
| - | Fichier : `td3/ | ||
| - | <sxh hcl> | ||
| - | variable " | ||
| - | type = string | ||
| - | description = "ARN de la Lambda de rotation fournie par AWS pour PostgreSQL" | ||
| - | default | ||
| - | } | ||
| - | |||
| - | resource " | ||
| - | count = var.rotation_lambda_arn != "" | ||
| - | secret_id | ||
| - | rotation_lambda_arn = var.rotation_lambda_arn | ||
| - | |||
| - | rotation_rules { | ||
| - | automatically_after_days = 30 | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Le bloc `count = var.rotation_lambda_arn != "" | ||
| - | |||
| - | Que signifie ce pattern dans Terraform ? | ||
| - | |||
| - | Pourquoi est-il utile de rendre la rotation optionnelle plutôt que obligatoire dans ce module ? | ||
| - | </ | ||
| - | |||
| - | <WRAP round help> | ||
| - | Après une rotation automatique du secret, l' | ||
| Si l' | Si l' | ||