Terraform permet de décrire votre infrastructure cloud dans des fichiers texte, de prévisualiser chaque changement avant de l’appliquer, puis de tout détruire d’une commande quand le laboratoire est terminé. C’est l’outil d’infrastructure as code le plus utilisé en entreprise et une compétence attendue de tout profil DevOps. Ce tutoriel s’adresse aux débutants : nous installons Terraform, configurons l’accès à AWS de façon sécurisée, puis créons un serveur web complet (groupe de sécurité, instance EC2 Amazon Linux 2023, nginx) avec les versions actuelles, Terraform 1.10+ et le fournisseur AWS 6.x.
Prérequis : un compte AWS (l’offre gratuite suffit), un terminal (Linux, macOS ou Windows avec WSL ou PowerShell) et des notions de base sur AWS (régions, EC2, VPC). Aucune expérience Terraform n’est nécessaire.
Étape 1 – Installer Terraform et l’AWS CLI
# Ubuntu / Debian : dépôt officiel HashiCorp
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install -y terraform awscli
# macOS
# brew tap hashicorp/tap && brew install hashicorp/tap/terraform awscli
# Windows (PowerShell)
# winget install Hashicorp.Terraform Amazon.AWSCLI
terraform version # Terraform v1.1x.x
aws --version # aws-cli/2.xÉtape 2 – Configurer l’accès à AWS sans clé permanente
N’utilisez jamais l’utilisateur root ni des clés d’accès copiées dans vos fichiers. La méthode recommandée en 2026 est IAM Identity Center (ex-AWS SSO) avec aws configure sso ; Terraform réutilise automatiquement la session. Si votre compte n’a pas Identity Center, créez un utilisateur IAM dédié avec une clé d’accès et stockez-la avec aws configure, jamais dans le code.
# Option A (recommandée) : IAM Identity Center
aws configure sso --profile labo
aws sso login --profile labo
export AWS_PROFILE=labo
# Option B : utilisateur IAM classique (clé stockée dans ~/.aws/credentials)
aws configure --profile labo
# AWS Access Key ID: AKIAIOSFODNN7EXAMPLE <- exemple fictif de la documentation AWS
# AWS Secret Access Key: ********
# Default region name: ca-central-1
aws sts get-caller-identity # vérifie l'identité et l'ID de compteÉtape 3 – Comprendre le vocabulaire
| Terme | Signification |
|---|---|
| Provider (fournisseur) | Plugin qui parle à une API : aws, azurerm, google, kubernetes… |
| Resource (ressource) | Un objet géré : une instance EC2, un bucket S3, un rôle IAM. |
| Data source | Lecture d’un objet existant : la dernière AMI, le VPC par défaut. |
| Variable / output | Paramètre d’entrée / valeur exportée (adresse IP, URL). |
| State (état) | Fichier JSON qui associe votre code aux identifiants réels des ressources. |
| Module | Groupe de ressources réutilisable avec ses propres entrées et sorties. |
Étape 4 – Écrire le projet
Créez un dossier terraform-debutant avec trois fichiers. Terraform lit tous les fichiers .tf du dossier ; la séparation n’est qu’une convention de lisibilité.
# versions.tf – versions de Terraform et du fournisseur
terraform {
required_version = ">= 1.10"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = var.region
default_tags {
tags = {
Projet = "terraform-debutant"
GerePar = "terraform"
}
}
}# variables.tf
variable "region" {
description = "Région AWS"
type = string
default = "ca-central-1"
}
variable "instance_type" {
description = "Type d'instance EC2"
type = string
default = "t3.micro"
validation {
condition = can(regex("^t3\\.", var.instance_type))
error_message = "Utilisez une instance de la famille t3 pour rester dans l'offre gratuite."
}
}
variable "mon_ip" {
description = "Votre adresse IP publique en notation CIDR, pour SSH (ex. 203.0.113.10/32)"
type = string
}# main.tf
# Dernière AMI Amazon Linux 2023 publiée par Amazon
data "aws_ami" "al2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-2023.*-x86_64"]
}
}
# On réutilise le VPC par défaut du compte pour ce premier projet
data "aws_vpc" "defaut" {
default = true
}
resource "aws_security_group" "web" {
name = "terraform-debutant-web"
description = "HTTP public, SSH depuis mon IP"
vpc_id = data.aws_vpc.defaut.id
}
resource "aws_vpc_security_group_ingress_rule" "http" {
security_group_id = aws_security_group.web.id
description = "HTTP depuis Internet"
cidr_ipv4 = "0.0.0.0/0"
from_port = 80
to_port = 80
ip_protocol = "tcp"
}
resource "aws_vpc_security_group_ingress_rule" "ssh" {
security_group_id = aws_security_group.web.id
description = "SSH depuis mon IP seulement"
cidr_ipv4 = var.mon_ip
from_port = 22
to_port = 22
ip_protocol = "tcp"
}
resource "aws_vpc_security_group_egress_rule" "tout" {
security_group_id = aws_security_group.web.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1"
}
resource "aws_instance" "web" {
ami = data.aws_ami.al2023.id
instance_type = var.instance_type
vpc_security_group_ids = [aws_security_group.web.id]
metadata_options {
http_tokens = "required" # IMDSv2 obligatoire (bonne pratique de sécurité)
}
user_data = <<-EOF
#!/bin/bash
dnf install -y nginx
echo "<h1>Bonjour depuis Terraform : $(hostname -f)</h1>" > /usr/share/nginx/html/index.html
systemctl enable --now nginx
EOF
tags = {
Name = "terraform-debutant-web"
}
}
output "url" {
description = "Adresse du serveur web"
value = "http://${aws_instance.web.public_ip}"
}
output "ami_utilisee" {
value = data.aws_ami.al2023.name
}Ajoutez enfin un fichier terraform.tfvars avec votre IP (obtenez-la avec curl -s https://checkip.amazonaws.com) :
# terraform.tfvars (à ne pas committer s'il contient des données personnelles)
mon_ip = "203.0.113.10/32"Étape 5 – Le cycle init, plan, apply
terraform init # télécharge le fournisseur AWS, crée .terraform.lock.hcl
terraform fmt # met en forme les fichiers
terraform validate # vérifie la syntaxe et les références
terraform plan # montre ce qui sera créé : « Plan: 5 to add, 0 to change, 0 to destroy. »
terraform apply # redemande confirmation : tapez yes
# Après une minute environ :
curl -s "$(terraform output -raw url)"
# <h1>Bonjour depuis Terraform : ip-172-31-xx-xx.ca-central-1.compute.internal</h1>Lisez attentivement la sortie de plan : le signe + indique une création, ~ une modification sur place, -/+ une destruction suivie d’une recréation (attention aux bases de données !) et - une suppression. Cette prévisualisation est la principale raison d’utiliser Terraform plutôt que la console.
Étape 6 – Modifier, puis détruire
# Changez le message dans user_data puis :
terraform plan
# ~ user_data ... forces replacement -> l'instance sera recréée (user_data ne s'exécute qu'au premier démarrage)
terraform apply
# Inspecter l'état
terraform state list
terraform state show aws_instance.web
terraform output
# Tout supprimer pour ne rien payer
terraform destroyLe fichier terraform.tfstate contient des informations sensibles (adresses IP, identifiants de ressources, parfois des mots de passe). Ne le committez jamais dans Git ; en équipe, stockez-le sur S3 avec verrouillage natif, comme expliqué dans Terraform remote state on S3.
Fichier .gitignore minimal
.terraform/
*.tfstate
*.tfstate.backup
*.tfvars # sauf si le fichier ne contient rien de sensible
crash.log
# Committez .terraform.lock.hcl : il fige les versions des fournisseursErreurs fréquentes des débutants
- « No valid credential sources found » – la session SSO a expiré ou
AWS_PROFILEn’est pas défini ; relancezaws sso login. - « UnauthorizedOperation » – l’identité IAM n’a pas les droits EC2 ; pour un labo, attachez la politique
AmazonEC2FullAccessà votre utilisateur ou groupe de permissions. - « Error: Reference to undeclared input variable » – variable utilisée mais non déclarée dans
variables.tf. - Page web inaccessible – attendez une minute (installation de nginx), puis vérifiez que la règle HTTP existe ; SSH échoue si votre IP a changé.
- Coûts inattendus – une instance oubliée coûte environ 8 $ par mois ; prenez l’habitude de
terraform destroyà la fin de chaque session et activez une alerte budgétaire AWS.
Pour aller plus loin
- Remplacer le VPC par défaut par un VPC dédié : Terraform AWS VPC.
- Découper le code en modules : Terraform modules.
- Créer plusieurs instances avec for_each et count.
- Automatiser
planetapplydans un pipeline avec des identifiants OIDC plutôt que des clés.
À retenir
- Terraform = code HCL + fournisseur + état, piloté par
init,plan,apply,destroy. - Configurez AWS avec Identity Center ou un profil nommé ; aucune clé dans le code.
- Lisez toujours le
plan; le-/+signale une recréation. - Protégez le fichier d’état et détruisez vos ressources de laboratoire.
La suite de la série (en anglais) commence par la vue d’ensemble Terraform. Documentation officielle : Get started with Terraform on AWS.


