
Le premier risque quand on débute sur AWS avec Terraform, ce n’est pas le code HCL, mais l’environnement autour. Si la région est mauvaise, si les credentials ne sont pas chargés, ou si vous choisissez une AMI codée en dur qui n’existe plus, votre premier terraform apply échoue avant même de vous apprendre quoi que ce soit. Ce guide sert à éliminer ces incertitudes.
Vous allez donc construire la plus petite configuration utile possible : un provider AWS, une data source pour lire l’identité courante, une autre pour retrouver automatiquement une AMI Ubuntu récente, puis une EC2 minimale. L’objectif n’est pas seulement de créer une instance, mais de comprendre l’enchaînement logique : se connecter, lire l’existant, puis créer.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Configurer le provider AWS avec la région
- Authentifier Terraform automatiquement depuis vos credentials AWS
- Lire l’identité courante (AWS account ID, ARN utilisateur)
- Récupérer dynamiquement une AMI avec
data "aws_ami" - Créer une première EC2 sans configuration réseau explicitée
- Extraire les IDs essentiels dans les outputs
Pourquoi commencer par ce guide
Section intitulée « Pourquoi commencer par ce guide »Sur libvirt, vous aviez surtout besoin d’un hyperviseur local et d’une image. Sur AWS, il faut d’abord prouver que Terraform sait parler au bon compte, dans la bonne région, avec des droits suffisants. C’est pour cela que ce guide commence par des lectures (aws_caller_identity, aws_ami) avant d’introduire une vraie ressource.
Si cette base est claire, les guides suivants deviennent beaucoup plus simples : vous saurez distinguer une erreur de credentials, une erreur de région et une erreur de configuration Terraform.
Prérequis
Section intitulée « Prérequis »- Terraform ≥ 1.11 installé
- AWS CLI configuré avec credentials (voir préparation)
- Compréhension basique de Terraform : variables, resources, outputs, data sources
Objectif
Section intitulée « Objectif »Vous allez construire une infrastructure minimale AWS :
- Configurer Terraform pour accéder à AWS (provider + credentials)
- Lire automatiquement l’AMI Ubuntu 22.04 la plus récente
- Créer une EC2 t2.micro (gratuit/quasi-gratuit)
- Afficher ses identifiants en outputs pour vérifier la création
Durée estimée : 10 minutes Coût : Gratuit (tier gratuit AWS) ou ~$0.01
Préparation
Section intitulée « Préparation »Vérifier AWS CLI
Section intitulée « Vérifier AWS CLI »Assurez-vous que AWS CLI et vos credentials sont configurés :
aws sts get-caller-identitySortie attendue :
{ "UserId": "AIDAXXXXXXXXXXXXXXXX", "Account": "123456789012", "Arn": "arn:aws:iam::123456789012:user/your-user"}Si vous voyez une erreur, configurez vos credentials AWS.
Créer le répertoire du lab
Section intitulée « Créer le répertoire du lab »mkdir -p ~/terraform-aws-provider-ec2cd ~/terraform-aws-provider-ec2Étape 1 — Déclarer le provider AWS et les versions
Section intitulée « Étape 1 — Déclarer le provider AWS et les versions »Créez versions.tf :
terraform { required_version = ">= 1.11.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } }}
provider "aws" { region = var.aws_region}Ce bloc dit à Terraform :
- Utiliser Terraform ≥ 1.11.0 (version à mineure stable)
- Charger le provider AWS ~5.0 (version 5.x)
- Se connecter à la région définie par
var.aws_region(defaultant àus-east-1)
Étape 2 — Déclarer les variables
Section intitulée « Étape 2 — Déclarer les variables »Créez variables.tf :
variable "aws_region" { description = "AWS region" type = string default = "us-east-1"}
variable "instance_name" { description = "Name tag for the EC2 instance" type = string default = "lab01-terraform-instance"}
variable "instance_type" { description = "EC2 instance type" type = string default = "t2.micro"}Ces variables vous permettront de changer de région ou de type sans modifier main.tf.
Étape 3 — Lire l’identité AWS courante
Section intitulée « Étape 3 — Lire l’identité AWS courante »Créez main.tf :
# Récupérer l'identité AWS actuelle pour afficher dans les outputsdata "aws_caller_identity" "current" {}Cette data source lit l’identité courante : qui êtes-vous, quel account, quel ARN. Zéro effet de bord — c’est une lecture uniquement.
Étape 4 — Lire l’AMI Ubuntu dynamiquement
Section intitulée « Étape 4 — Lire l’AMI Ubuntu dynamiquement »Toujours dans main.tf, ajoutez :
# Lire l'AMI Ubuntu la plus récentedata "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] # Canonical (Ubuntu)
filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] }
filter { name = "virtualization-type" values = ["hvm"] }}Cette data source cherche l’AMI la plus récente qui correspond aux critères :
- Propriétaire : Canonical (ID
099720109477) - Nom : images Ubuntu 22.04 (Jammy) — le
*accepte les variantes (patch updates) - Type : HVM (hyperviseur standard)
Résultat : vous obtenez toujours l’Ubuntu 22.04 à jour sans coder l’ID d’une AMI spécifique.
Étape 5 — Créer la première EC2
Section intitulée « Étape 5 — Créer la première EC2 »Toujours dans main.tf, complétez :
# Créer une première instance EC2resource "aws_instance" "lab01_vm" { ami = data.aws_ami.ubuntu.id instance_type = var.instance_type
tags = { Name = var.instance_name }}Cette ressource crée une EC2 :
ami: utilise l’ID d’AMI récupéré par la data sourceinstance_type:t2.micro(gratuit ou quasi-gratuit)tags: une étiquette pour identifier l’instance dans la console AWS
Étape 6 — Déclarer les outputs
Section intitulée « Étape 6 — Déclarer les outputs »Créez outputs.tf :
output "aws_caller_identity_account_id" { description = "AWS Account ID" value = data.aws_caller_identity.current.account_id}
output "aws_caller_identity_user_arn" { description = "ARN of the AWS user/role" value = data.aws_caller_identity.current.arn}
output "ubuntu_ami_id" { description = "Ubuntu AMI ID used for the instance" value = data.aws_ami.ubuntu.id}
output "ubuntu_ami_name" { description = "Ubuntu AMI name" value = data.aws_ami.ubuntu.name}
output "instance_id" { description = "EC2 Instance ID" value = aws_instance.lab01_vm.id}
output "instance_arn" { description = "EC2 Instance ARN" value = aws_instance.lab01_vm.arn}
output "instance_public_ip" { description = "Public IP address of the instance" value = aws_instance.lab01_vm.public_ip}
output "instance_private_ip" { description = "Private IP address of the instance" value = aws_instance.lab01_vm.private_ip}Ces outputs afficheront les identifiants clés après apply, vous permettant de vérifier qu’Terraform a bien créé ce qu’it fallait.
Étape 7 — Créer le fichier tfvars
Section intitulée « Étape 7 — Créer le fichier tfvars »Créez terraform.tfvars :
aws_region = "us-east-1"instance_name = "lab01-terraform-instance"instance_type = "t2.micro"Vérification
Section intitulée « Vérification »Exécutez le lab complètement :
-
Initialiser Terraform :
Fenêtre de terminal terraform initSortie attendue :
Initializing the backend...Initializing provider plugins...- Finding hashicorp/aws versions matching "~> 5.0"...- Installing hashicorp/aws v5.100.0...Terraform has successfully created the lock file .terraform.lock.hclTerraform has been successfully initialized! -
Valider la configuration :
Fenêtre de terminal terraform validateSortie attendue :
Success! The configuration is valid. -
Afficher le plan :
Fenêtre de terminal terraform planSortie attendue (résumé) :
data.aws_caller_identity.current: Reading...data.aws_ami.ubuntu: Reading...data.aws_caller_identity.current: Read complete after 1s [id=276757567417]data.aws_ami.ubuntu: Read complete after 2s [id=ami-00de3875b03809ec5]Terraform will perform the following actions:# aws_instance.lab01_vm will be created+ resource "aws_instance" "lab01_vm" {+ ami = "ami-00de3875b03809ec5"+ instance_type = "t2.micro"+ tags = {+ "Name" = "lab01-terraform-instance"}}Plan: 1 to add, 0 to change, 0 to destroy. -
Appliquer la configuration :
Fenêtre de terminal terraform apply -auto-approveSortie attendue (fin) :
aws_instance.lab01_vm: Still creating... [00m30s elapsed]aws_instance.lab01_vm: Creation complete after 34s [id=i-017ec14c04dd2ccd2]Apply complete! Resources: 1 added, 0 changed, 0 destroyed.Outputs:aws_caller_identity_account_id = "276757567417"aws_caller_identity_user_arn = "arn:aws:iam::276757567417:user/stephane_robert"instance_arn = "arn:aws:ec2:us-east-1:276757567417:instance/i-017ec14c04dd2ccd2"instance_id = "i-017ec14c04dd2ccd2"instance_private_ip = "172.31.21.186"instance_public_ip = "54.89.158.175"ubuntu_ami_id = "ami-00de3875b03809ec5"ubuntu_ami_name = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-20260320" -
Vérifier l’instance dans la console AWS (optionnel) :
Fenêtre de terminal aws ec2 describe-instances --instance-ids i-017ec14c04dd2ccd2
Anatomie
Section intitulée « Anatomie »Provider AWS
Section intitulée « Provider AWS »Le bloc provider "aws" dit à Terraform :
- Où se connecter (région)
- Comment s’authentifier (credentials automatiques)
- Version du provider (gérée par
required_providers)
Contrairement à libvirt où vous définissez l’URI du socket KVM, AWS provider met vos credentials à jour automatiquement.
Data sources vs Resources
Section intitulée « Data sources vs Resources »| Aspect | Data source | Resource |
|---|---|---|
| Crée quelque chose ? | ❌ Non | ✅ Oui |
| Usage | Lire l’infrastructure existante | Créer/modifier l’infrastructure |
| Exemple | data "aws_ami", data "aws_caller_identity" | resource "aws_instance" |
Dans ce lab :
data "aws_caller_identity": lit votre identitédata "aws_ami": trouve une AMI déjà disponibleresource "aws_instance": crée une nouvelle EC2
Les outputs affichent les valeurs importantes après que apply s’exécute. C’est utile pour :
- Vérifier les IDs créés
- Partager l’adresse IP avec une équipe
- Utiliser dans d’autres workflows (scripts de post-config)
Bonnes pratiques
Section intitulée « Bonnes pratiques »1. Utiliser les data sources plutôt que coder l’ID
Section intitulée « 1. Utiliser les data sources plutôt que coder l’ID »# ❌ Hardcodé — fragileami = "ami-00de3875b03809ec5"
# ✅ Dynamique — toujours à jourdata "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] filter { ... }}ami = data.aws_ami.ubuntu.id2. Utiliser les versions épinglées
Section intitulée « 2. Utiliser les versions épinglées »# ❌ Risquéversion = ">= 5.0"
# ✅ Contrôléversion = "~> 5.0" # ✅ 5.x, mais pas 6.0+3. Ajouter des tags systématiquement
Section intitulée « 3. Ajouter des tags systématiquement »tags = { Name = "lab01-instance" Environment = "lab" ManagedBy = "terraform" CreatedAt = "2026-04-01"}4. Utiliser un .gitignore pour les fichiers sensibles
Section intitulée « 4. Utiliser un .gitignore pour les fichiers sensibles »cat > .gitignore << EOF.terraform/.terraform.lock.hclterraform.tfstate**.tfvarsEOFDépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
Error: error configuring Terraform AWS Provider: no valid credential sources for Terraform AWS Provider found | Credentials AWS manquantes | Exécuter aws configure ou exporter AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY |
Error: your query returned no results. Please change your search criteria | L’AMI n’existe pas dans votre région | Changer la région (aws_region) ou ajuster le filtre AMI |
Error: AuthFailure | Utilisateur AWS n’a pas les permissions ec2:RunInstances | Ajouter la policy AmazonEC2FullAccess au user IAM |
| Instance créée mais pas visible dans la console | Cache du navigateur | Rafraîchir ou attendre 30 secondes |
Nettoyage
Section intitulée « Nettoyage »Après le lab, détruisez l’infrastructure pour ne pas être inutilement facturé :
terraform destroy -auto-approveSortie attendue :
aws_instance.lab01_vm: Destroying... [id=i-017ec14c04dd2ccd2]aws_instance.lab01_vm: Still destroying... [id=i-017ec14c04dd2ccd2, 00m10s elapsed]aws_instance.lab01_vm: Destruction complete after 41s
Destroy complete! Resources: 1 destroyed.Nettoyez les fichiers Terraform locaux :
rm -rf .terraform* terraform.tfstate*À retenir
Section intitulée « À retenir »- Le provider AWS se configure par région et credentials — Terraform les charge automatiquement
- Les data sources (
aws_ami,aws_caller_identity) lisent l’infrastructure existante sans la modifier - Les ressources (
aws_instance) créent l’infrastructure - Les versions épinglées (~> X.Y) vous protègent des breaking changes
- Les outputs vérifient que Terraform a bien créé ce qu’it fallait
- Le nettoyage (
destroy) est ESSENTIEL pour ne pas être facturé inutilement - Les tags aident à tracer qui a créé quoi