Introduction au Lab 2
Ce TP a pour objectif de nous familiariser avec le déploiement d’infrastructure cloud sur AWS en utilisant différents outils d’automatisation : des scripts Bash, Ansible, Packer et OpenTofu. Nous allons progressivement passer d’une approche manuelle avec des scripts à une approche déclarative et modulaire.
Section 2 : Deploying an EC2 Instance Using a Bash Script
1. Set Up the Directory Structure
On crée le dossier bash dans le dossier script.
2. Create the User Data Script
On copie le script user data dans le fichier user-data.sh.
3. Create the Bash Script
On crée le fichier deploy-ec2-instance.sh et on copie le script provenant du sujet.
5. Run the Script
On lance l’instance EC2.

6. Test the Deployment
Le déploiement est testé avec succès.

Exercices
Exercice 1 :
What happens if you run the script a second time? Try it and observe the output. Explain why this happens. Hint: Consider resource names and uniqueness in AWS.
Quand on essaye de relancer la commande, on obtient cette erreur :
bash git:(main) ✗ ./deploy-ec2-instance.sh
An error occurred (InvalidGroup.Duplicate) when calling the CreateSecurityGroup operation:
The security group 'sample-app' already exists for VPC 'vpc-030743539e69419e7'Cette erreur signifie que notre requête échoue car notre script va simplement créer une ressource AWS sans vérifier si une ressource n’existe pas déjà avec ce nom. Or, dans AWS, les noms des security groups doivent être uniques. AWS refuse donc de créer une ressource dont le nom existe déjà et renvoie une erreur.
Exercice 2 :
Modify the script to deploy multiple EC2 instances. How would you adjust the script to handle this?
Pour que le script fonctionne quand même, il faudrait changer le nom de l’instance en mettant un nom unique.
Section 3: Deploying an EC2 Instance Using Ansible
2. Create the Ansible Playbook for EC2 Deployment
On crée le fichier create_ec2_instance_playbook.yml et on copie le code donné dans le sujet.
3 - Exécution du Playbook
On lance le Playbook.

On voit avec failed=0 et changed=1 que l’instance a bien été déployée.
4. Set Up the Ansible Inventory
On crée l’inventaire inventory.aws_ec2.yml.
5. Create Group Variables
On crée le dossier group_vars puis le fichier ch2_instances.yml.
6. Create the Ansible Playbook for Configuration
On crée le fichier configure_sample_app_playbook.yml.
7. Create the Ansible Role
On crée la structure de dossiers demandée puis on copie app.js.
8. Run the Configuration Playbook
Le playbook de configuration est exécuté avec succès.

9. Test the Deployment
Ici nous avons essayé de tester le déploiement de l’application en allant sur l’URL http://18.224.32.181:8080.
Cependant, nous ne sommes pas parvenues à ouvrir la page, elle ne faisait que charger en continu sans me donner de résultat.
Nous avons donc recherché la cause probable.

En cherchant, nous avons trouvé que nous pouvions voir le contenu de ma page avec ces deux commandes :
# Connecte-toi à l'instance
ssh -i ansible-ch2.key ec2-user@18.224.32.181
# Une fois dedans, teste si l'app répond localement
curl http://localhost:8080Et nous sommes parvenues à avoir le résultat Hello World ! :
➜ ansible git:(main) ✗ ssh -i ansible-ch2.key ec2-user@18.224.32.181
The authenticity of host '18.224.32.181 (18.224.32.181)' can't be established.
ED25519 key fingerprint is SHA256:3bodBEl5o4XI0lES3SI3RSR5ubXp4l8dCDBjQZCxNe0.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:3: ec2-18-224-32-181.us-east-2.compute.amazonaws.com
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '18.224.32.181' (ED25519) to the list of known hosts.
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
Last login: Fri Feb 6 14:55:18 2026 from 79.174.206.181
[ec2-user@ip-172-31-12-249 ~]$ curl http://localhost:8080
Hello, World!
[ec2-user@ip-172-31-12-249 ~]$Ainsi, selon nos recherches, le problème est sûrement dû au Security Group d’AWS qui bloque les connexions venant de notre navigateur vers le port 8080.
Pour réussir tout de même à ouvrir l’URL dans notre navigateur, nous avons essayé de faire cette commande :
➜ ansible git:(main) ✗ aws ec2 authorize-security-group-ingress \
--group-name sample-app-ansible \
--protocol tcp \
--port 8080 \
--cidr 0.0.0.0/0
An error occurred (InvalidPermission.Duplicate) when calling the AuthorizeSecurityGroupIngress operation:
the specified rule "peer: 0.0.0.0/0, TCP, from port: 8080, to port: 8080, ALLOW" already existsNous avons eu une erreur à la suite de cette requête, mais en essayant à nouveau d’ouvrir l’URL, la page s’est bien affichée. Nous ne savons pas si c’est grâce à la commande ou parce que nous avons changé de wifi, mais finalement ça marche !

Exercices
Exercice 3 :
What happens if you run the configuration playbook a second time? Observe and explain. Hint: Consider idempotency in Ansible tasks.
Si nous essayions de relancer la commande ansible-playbook -i inventory.aws_ec2.yml configure_sample_app_playbook.yml, nous ne voyons pas de changement.
Le résultat que nous obtenons ne nous semble pas différent de la première fois que nous avons lancé la commande.

Hint — Idempotence dans Ansible : Ansible est conçu pour être idempotent, ce qui signifie que rejouer le même playbook ne modifie rien si l’état souhaité est déjà atteint. Les tâches vérifient l’état actuel avant d’agir.
Exercice 4 :
Modify the playbook to deploy and configure multiple EC2 instances. How would you adjust the playbook and inventory?
Afin de pouvoir créer plusieurs instances en même temps, nous avons ajouté des lignes de code dans le fichier create_ec2_instance_playbook.yml.

Nous n’avons pas changé l’inventaire ni le Playbook car nous avons vu que cela n’avait pas besoin d’être changé et que cela se faisait automatiquement.
Ensuite j’ai nettoyé le tout pour passer à la section 4.

Section 4 : Creating a VM Image Using Packer
1. Set Up the Directory Structure
On crée la structure de répertoires.
2. Copy the Node.js Sample App
On copie l’application Node.js Sample App.
3. Create the Packer Template
On crée le fichier sample-app.pkr.hcl et on copie le code donné dans le sujet. On a eu besoin d’installer Packer préalablement.

4. Initialize Packer
On initialise et on construit notre AMI avec Packer.

5. Build the AMI
On construit notre AMI.


On peut voir que notre AMI a bien été créée :

Exercices
Exercice 5 :
What happens if you run packer build a second time? Explain why. Hint: Consider the uniqueness of the ami name .
Normalement, si on relance exactement la même commande sans rien modifier, on va obtenir une erreur car AWS interdit d’avoir deux AMIs avec le même identifiant. Sauf que dans notre fichier, nous avons nommé notre AMI comme suit :
ami_name = "sample-app-packer-${uuidv4()}"Ainsi, grâce à la fonction uuidv4(), Packer va générer un identifiant unique à chaque fois que l’on construit une nouvelle AMI.
Donc, si on relance la commande, build va créer une nouvelle AMI avec un nom différent et un nouvel ID, et ne va pas générer d’erreur.
Exercice 6 :
Modify the Packer template to create images for another cloud provider or for local use (e.g., VirtualBox).
Nous avons compris que Packer est multi-provider, ce qui signifie que l’on peut utiliser plusieurs services cloud en même temps.
Pour changer de service, il faut modifier deux sections dans le fichier sample-app.pkr.hcl :
- Dans un premier temps, il faut modifier le bloc
packer {}(les plugins) et ajouter le plugin du nouveau service cloud. - Ensuite, il faut modifier le bloc
source {}en remplaçantamazon-ebspar le type correspondant au nouveau service.
Avant de passer à la section 5, j’ai bien désenregistré l’AMI.

Section 5 : Deploying, Updating, and Destroying an EC2 Instance Using OpenTofu
1. Set Up the Directory Structure
On crée la structure du dossier.
2. Create the Main Configuration File
On crée le fichier main.

3. Create the Variables File
On crée le fichier variables.

4. Create the User Data Script
On crée le fichier User Data script.

5. Create the Outputs File
On crée le fichier output.

6. Initialize OpenTofu
Avant d’initialiser tofu, j’installe OpenTofu.

Ensuite, je lance l’initialisation de tofu.

7. Apply the Configuration
Ensuite, je lance tofu apply et j’entre l’identifiant de mon AMI créée avec Packer.



Après avoir validé, la configuration est appliquée avec succès.

8. Test the Deployment
Ensuite, nous pouvons tester le déploiement en allant à l’URL http://3.143.143.144:8080.

9. Update the Configuration
Nous avons bien appliqué la modification :

Nous avons relancé tofu apply :

Ensuite, je détruis les ressources.



Les ressources ont bien été détruites.
Exercices
Exercice 7 :
What happens if you run tofu apply after the resources have been destroyed? Explain the behavior.
Si l’on relance tofu apply après la destruction, aucun changement n’apparaît au sens d’erreur, en effet, les ressources sont bien recréées.


En effet, même si nous avons tout détruit, tofu compare notre code et le State file. Comme le State file est vide, tofu va recréer toutes les ressources.
Exercice 8 :
How would you modify the OpenTofu code to deploy multiple EC2 instances? Implement this change using a loop or by defining multiple resources.
Pour déployer plusieurs instances EC2, il suffit d’ajouter une ligne count dans le bloc resource du fichier main :
resource "aws_instance" "sample_app" {
count = 2
# ...
}
Section 6 : Deploying an EC2 Instance Using an OpenTofu Module
1. Set Up the Modules Directory
On crée la structure de répertoires.
2. Create the Root Module
On crée le module.
3. Create the Main Configuration File
On crée le fichier main et on copie le code donné.

4. Modify the Module to Use Variables
On modifie le fichier variables.

5. Update main.tf in the Module to Use var.name
On actualise le fichier main en ajoutant var.name pour donner le nom à travers une variable.

6. Initialize OpenTofu
On lance l’initialisation d’OpenTofu.

7. Apply the Configuration
L’initialisation fonctionnait parfaitement, mais lorsque nous avons voulu lancer tofu apply -var ami_id=ami-08473fbb358a1464d, nous avons obtenu plusieurs erreurs.

Nous avons donc modifié nos codes pour résoudre ces erreurs :
- Dans le fichier
main, nous avons modifié le contenu deami_id.

- Dans le fichier
variables, nous avons ajouté la variable"ami_id".

- Nous avons complété le code dans le
maindu module.

- Nous avons ajouté un fichier
variable.tfdanslivepour déclarer la variable"ami_id".

Ensuite on a relancé la commande pour la configuration et cette fois-ci, on n’avait plus aucune erreur et tout a fonctionné.




8. Test the Deployment
Maintenant, nous pouvons récupérer les deux adresses IP publiques de nos instances.

Pour la première instance, on saisit cette URL dans notre navigateur : http://3.133.105.77:8080

Puis on teste la deuxième instance avec cette URL : http://3.138.182.226:8080
{width=80%}
Exercices
Exercice 9 :
Modify the module to accept additional parameters like port . Update the root module to pass these parameters.
On a modifié le code de variables.tf de ec2-instance pour que le module accepte plusieurs paramètres.

On a également modifié le main de ec2-instance.

Ensuite on a relancé l’initialisation avec tofu init puis tofu apply -var ami_id=ami-08473fbb358a1464d.

On a également ajouté instance_type = "t3.micro" dans le main de sample-app, sinon nous avions une erreur lors de tofu apply -var ami_id=ami-08473fbb358a1464d.


Exercice 10 :
Use OpenTofu’s count or for each to deploy multiple instances without duplicating code in the root module.
Pour faire cela, on a ajouté la boucle for_each dans le main de sample-app :

Ensuite on a modifié les outputs de sample-app car sinon nous avions une erreur.

Ensuite j’ai relancé l’initialisation avec tofu init puis tofu apply -var ami_id=ami-08473fbb358a1464d.
Nous avons dû faire au préalable tofu destroy -var ami_id=ami-08473fbb358a1464d car nous avions une erreur avec l’unicité des noms des variables des groupes de sécurité.


On peut saisir l’URL avec les adresses IP et retrouver notre application sur le navigateur :
- Pour la première instance :
http://3.142.51.82:8080

- Pour la deuxième instance :
http://3.150.117.170:8080

Section 7: Using OpenTofu Modules from GitHub
Après avoir essayé avec le code déjà donné dans le main.tf de sample-app-github, nous avons obtenu de nombreuses erreurs.
Alors, on a modifié outputs et créé un fichier variable, mais cela ne fonctionnait toujours pas.
Nous avons finalement modifié le main.tf et les outputs et nous avons enfin réussi à lancer sans erreur tofu apply -var ami_id=ami-08473fbb358a1464d.
Fichier main :

Fichier outputs :

Fichier variables :

2. Initialize OpenTofu
On lance l’initialisation d’OpenTofu.
3. Apply the Configuration
On applique la configuration avec tofu apply.

4. Test the Deployment
Si l’on saisit l’URL, on retrouve bien notre application sur le navigateur web : http://18.218.248.209:8080

Exercices
Exercice 11 :
Explore the use of versioning with modules by specifying a specific Git tag or commit in the module source.
Pour cette question, nous avons ajouté ?ref=v0.0.1 à la fin de l’URL de la source GitHub dans le fichier main.tf de sample-app-github.
Grâce à cet ajout, même si l’auteur du répertoire GitHub modifie quelque chose sur celui-ci, notre commande tofu apply parviendra toujours à fonctionner. Cela nous permet de choisir la version que nous utilisons.

Exercice 12 :
Find an OpenTofu module in the Terraform Registry or another public repository and use it in your configuration.
On a regardé le catalogue public Terraform Registry regroupant énormément de modules écrits par des experts et les services cloud. Contrairement à GitHub où l’on utilise une URL complète, le Registry permet d’utiliser un nom court et un argument version dédié, ce qui nous permet de garantir la stabilité de notre code.
On a donc modifié le main de sample-app-github en ajoutant le module "vpc" :
Il a fallu aussi changer la référence mise lors de la question 10 car cela ne fonctionnait pas sinon.

Nous avond commenté tous les outputs aussi, sinon cela ne fonctionnait pas.

J’ai lancé la commande tofu init -upgrade. L’argument -upgrade est important pour forcer OpenTofu à oublier l’erreur du tag v0.0.1 et à prendre la branche main, sinon cela ne fonctionne pas.

Puis nous avons lancé : tofu apply -var ami_id=ami-08473fbb358a1464d
Et cela a bien fonctionné !

Conclusion
Ce TP nous a permis de découvrir et de comparer plusieurs outils essentiels au déploiement d’infrastructure cloud sur AWS. Nous avons commencé par des scripts Bash simples pour des déploiements rapides puis nous avons continué avec Ansible pour la configuration idempotente des serveurs, Packer pour la création d’images reproductibles mais également des modules comme OpenTofu réutilisables.
Au final, ce TP pose les bases concrètes de l’Infrastructure as Code (IaC) que nous avons ensuite pu approfondir avec la mise en place d’un pipeline CI/CD complet dans le Lab 5.