AWS avec Terraform : détruire, reconstruire et faire évoluer l’infrastructure — Partie 2/2

Point de départ
Dans la partie 1, nous avons décrit le réseau, la sécurité, l’EC2 et Nginx avec Terraform. Le service fonctionne et un nouveau terraform plan ne détecte plus aucun changement.
| Il reste à vérifier l’essentiel : notre infrastructure est-elle réellement reproductible ? |
Détruire l’infrastructure
Nous supprimons volontairement tout ce qui est géré par ce projet :
terraform destroy
Après confirmation :
Destroy complete! Resources: 9 destroyed.

À cet instant, le code existe toujours, mais l’infrastructure AWS n’existe plus.
Reconstruire à partir du même code
terraform plan -out=tfplan
terraform apply tfplan
terraform output -raw web_url
Terraform recrée le VPC, le subnet, le routage, le Security Group, l’EC2 et Nginx. La page réapparaît, avec une nouvelle adresse IP publique.

| La machine n’a pas été restaurée : une nouvelle EC2 a été créée à partir du même code. C’est la preuve recherchée. |
Modifier l’application
Nous poussons le test un peu plus loin en modifiant le HTML du user_data pour publier une Version 2. Avant de modifier le code, repérons l’option qui va déterminer le comportement de Terraform.
Où se trouve user_data_replace_on_change ?
Cette option se trouve dans le fichier compute.tf, à l’intérieur de la ressource aws_instance « web » qui crée notre instance EC2. Elle est placée juste avant le bloc user_data :
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web.id]
associate_public_ip_address = true
user_data_replace_on_change = true
user_data = <<-EOF
#!/bin/bash
...
EOF
}
user_data_replace_on_change n’est ni une option de la console AWS ni une commande Terraform : c’est un paramètre de la ressource aws_instance. Lorsqu’il vaut true, une modification du user_data indique à Terraform qu’il doit remplacer l’instance afin que la nouvelle EC2 démarre avec le nouveau script.
Dans notre lab, cela signifie que modifier quelques lignes de la page web entraîne la destruction de l’ancienne EC2 et la création d’une nouvelle. Le VPC, le subnet, le routage et le Security Group ne sont pas concernés par ce changement.
<h1>SAYOOS DevOps Lab — Version 2</h1>
<p>Cette infrastructure AWS a été mise à jour à partir du code Terraform.</p>
<div class="status">
<strong>Statut :</strong> nouvelle version déployée avec succès
</div>
<p>
VPC : 10.10.0.0/16<br>
Subnet : 10.10.10.0/24<br>
Région : Europe (Paris)
</p>
terraform fmt
terraform validate
terraform plan
Après la modification du user_data, Terraform détecte le changement et, grâce à user_data_replace_on_change = true, prévoit le remplacement ciblé de l’EC2 :
Plan: 1 to add, 0 to change, 1 to destroy.
terraform plan -out=tfplan
terraform apply tfplan

Le VPC, le subnet et le Security Group restent en place. Grâce à user_data_replace_on_change = true, Terraform remplace uniquement l’EC2 concernée par le changement.
L’adresse IP change : que ferait-on en production ?
Une adresse IP publique attribuée automatiquement à une EC2 n’est pas une identité durable du service. Pour un besoin simple, une Elastic IP peut fournir une adresse fixe. Pour une architecture plus professionnelle, on expose plutôt un nom DNS stable devant un load balancer.

Avec AWS Certificate Manager, on peut également publier le service en HTTPS. Les serveurs peuvent alors être remplacés sans changer l’adresse utilisée par les clients.
Faire évoluer ce laboratoire
Cette première infrastructure est un socle. On peut augmenter progressivement son niveau d’industrialisation sans repartir de zéro.

Parmi les prochaines étapes : Route 53, HTTPS/ACM, ALB, subnets privés et Multi-AZ, Auto Scaling, RDS, supervision, remote state, modules et CI/CD.
Séparer les responsabilités
Dans ce TP, user_data installe Nginx. C’est suffisant pour le lab, mais remplacer une EC2 pour quelques lignes HTML montre rapidement la limite de cette approche.

Terraform construit l’infrastructure. Ansible configure les serveurs. La CI/CD déploie l’application. Cette séparation devient utile dès que le projet grandit.
En entreprise, qu’est-ce qui changerait ?
Le lab utilise une seule EC2 publique et un state local. En production, on viserait plutôt des instances privées derrière un Load Balancer, plusieurs Availability Zones, HTTPS, supervision, sauvegardes, gestion des secrets et journalisation centralisée.
Le state Terraform serait placé dans un backend distant, protégé et partagé. Le code serait organisé en modules et en environnements distincts (dev, staging, production), puis exécuté depuis une pipeline CI/CD avec revue du plan avant application.
Conclusion
Nous avons construit l’infrastructure, puis nous l’avons détruite et reconstruite à partir du même code. Nous avons ensuite modifié l’état désiré et observé Terraform ne remplacer que l’EC2 concernée.
| L’infrastructure n’est plus seulement ce que l’on voit dans la console AWS : elle est décrite, versionnée, reproductible et prête à évoluer. |
La suite logique sera de traiter la configuration des serveurs avec Ansible : « Nos serveurs sont tous configurés différemment : comment garantir une configuration identique ? »