Aller au contenu
Infrastructure as Code medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Terraform AWS — Déployer une première EC2

15 min de lecture

logo terraform

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.

  • 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

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.

  • Terraform ≥ 1.11 installé
  • AWS CLI configuré avec credentials (voir préparation)
  • Compréhension basique de Terraform : variables, resources, outputs, data sources

Vous allez construire une infrastructure minimale AWS :

  1. Configurer Terraform pour accéder à AWS (provider + credentials)
  2. Lire automatiquement l’AMI Ubuntu 22.04 la plus récente
  3. Créer une EC2 t2.micro (gratuit/quasi-gratuit)
  4. 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

Assurez-vous que AWS CLI et vos credentials sont configurés :

Fenêtre de terminal
aws sts get-caller-identity

Sortie attendue :

{
"UserId": "AIDAXXXXXXXXXXXXXXXX",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/your-user"
}

Si vous voyez une erreur, configurez vos credentials AWS.

Fenêtre de terminal
mkdir -p ~/terraform-aws-provider-ec2
cd ~/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)

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.

Créez main.tf :

# Récupérer l'identité AWS actuelle pour afficher dans les outputs
data "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.

Toujours dans main.tf, ajoutez :

# Lire l'AMI Ubuntu la plus récente
data "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.

Toujours dans main.tf, complétez :

# Créer une première instance EC2
resource "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 source
  • instance_type : t2.micro (gratuit ou quasi-gratuit)
  • tags : une étiquette pour identifier l’instance dans la console AWS

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.

Créez terraform.tfvars :

aws_region = "us-east-1"
instance_name = "lab01-terraform-instance"
instance_type = "t2.micro"

Exécutez le lab complètement :

  1. Initialiser Terraform :

    Fenêtre de terminal
    terraform init

    Sortie 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.hcl
    Terraform has been successfully initialized!
  2. Valider la configuration :

    Fenêtre de terminal
    terraform validate

    Sortie attendue :

    Success! The configuration is valid.
  3. Afficher le plan :

    Fenêtre de terminal
    terraform plan

    Sortie 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.
  4. Appliquer la configuration :

    Fenêtre de terminal
    terraform apply -auto-approve

    Sortie 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"
  5. Vérifier l’instance dans la console AWS (optionnel) :

    Fenêtre de terminal
    aws ec2 describe-instances --instance-ids i-017ec14c04dd2ccd2

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.

AspectData sourceResource
Crée quelque chose ?❌ Non✅ Oui
UsageLire l’infrastructure existanteCréer/modifier l’infrastructure
Exempledata "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à disponible
  • resource "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)

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é — fragile
ami = "ami-00de3875b03809ec5"
# ✅ Dynamique — toujours à jour
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter { ... }
}
ami = data.aws_ami.ubuntu.id
# ❌ Risqué
version = ">= 5.0"
# ✅ Contrôlé
version = "~> 5.0" # ✅ 5.x, mais pas 6.0+
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 »
Fenêtre de terminal
cat > .gitignore << EOF
.terraform/
.terraform.lock.hcl
terraform.tfstate*
*.tfvars
EOF
SymptômeCause probableSolution
Error: error configuring Terraform AWS Provider: no valid credential sources for Terraform AWS Provider foundCredentials AWS manquantesExécuter aws configure ou exporter AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY
Error: your query returned no results. Please change your search criteriaL’AMI n’existe pas dans votre régionChanger la région (aws_region) ou ajuster le filtre AMI
Error: AuthFailureUtilisateur AWS n’a pas les permissions ec2:RunInstancesAjouter la policy AmazonEC2FullAccess au user IAM
Instance créée mais pas visible dans la consoleCache du navigateurRafraîchir ou attendre 30 secondes

Après le lab, détruisez l’infrastructure pour ne pas être inutilement facturé :

Fenêtre de terminal
terraform destroy -auto-approve

Sortie 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 :

Fenêtre de terminal
rm -rf .terraform* terraform.tfstate*
  1. Le provider AWS se configure par région et credentials — Terraform les charge automatiquement
  2. Les data sources (aws_ami, aws_caller_identity) lisent l’infrastructure existante sans la modifier
  3. Les ressources (aws_instance) créent l’infrastructure
  4. Les versions épinglées (~> X.Y) vous protègent des breaking changes
  5. Les outputs vérifient que Terraform a bien créé ce qu’it fallait
  6. Le nettoyage (destroy) est ESSENTIEL pour ne pas être facturé inutilement
  7. Les tags aident à tracer qui a créé quoi

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn