Leçon 6 / 6
Leçon 06 · Partie 2 — Aller plus loin

Projet récap — Déployer une infra cloud

Objectif du projet

Dans ce projet final, tu vas déployer une infrastructure complète sur AWS en utilisant tout ce que tu as appris. À la fin, tu auras un serveur web accessible sur Internet, provisionné entièrement avec du code Terraform.

Le résultat final comprend :

  • Un VPC dédié avec un sous-réseau public
  • Une internet gateway et une table de routage pour l'accès Internet
  • Un security group autorisant SSH (port 22) et HTTP (port 80)
  • Une instance EC2 avec Nginx installé au démarrage
  • Une IP élastique (Elastic IP) pour une adresse IP fixe
💡

Ce projet utilise le Free Tier AWS. L'instance t2.micro est gratuite pendant 750 heures/mois pour les nouveaux comptes. Pense à faire terraform destroy après pour ne pas être facturé.

Structure du projet

On organise le code en quatre fichiers, selon les bonnes pratiques Terraform :

# Arborescence du projet
projet-infra/
├── main.tf          # ressources principales
├── variables.tf     # déclaration des variables
├── outputs.tf       # valeurs de sortie
└── terraform.tfvars # valeurs concrètes des variables

Crée un nouveau dossier et place-toi dedans :

mkdir projet-infra
cd projet-infra

Le fichier variables.tf

Ce fichier déclare toutes les variables que le projet utilise. Les valeurs seront renseignées dans terraform.tfvars.

# variables.tf

variable "aws_region" {
  description = "Région AWS à utiliser"
  type        = string
  default     = "eu-west-3"  # Paris
}

variable "ami_id" {
  description = "ID de l'AMI Amazon Linux 2023"
  type        = string
}

variable "instance_type" {
  description = "Type d'instance EC2"
  type        = string
  default     = "t2.micro"
}

variable "project_name" {
  description = "Nom du projet (utilisé dans les tags)"
  type        = string
  default     = "monminilab-web"
}

Et le fichier terraform.tfvars avec les valeurs réelles :

# terraform.tfvars

aws_region    = "eu-west-3"
ami_id        = "ami-0f61de2873e29e866"  # Amazon Linux 2023, eu-west-3
instance_type = "t2.micro"
project_name  = "monminilab-web"
⚠️

L'ID d'une AMI varie selon la région et change régulièrement. Pour trouver le bon ID pour ta région, va dans la console AWS → EC2 → AMIs et filtre sur "Amazon Linux 2023".

Le fichier main.tf

C'est le cœur du projet. On y déclare toutes les ressources, dans l'ordre logique du réseau vers le serveur.

Provider et configuration

# main.tf — provider

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

VPC et réseau

# VPC principal
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true

  tags = {
    Name    = "${var.project_name}-vpc"
    Project = var.project_name
  }
}

# Sous-réseau public
resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  map_public_ip_on_launch = true

  tags = {
    Name    = "${var.project_name}-subnet-public"
    Project = var.project_name
  }
}

# Internet Gateway — connexion vers Internet
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name    = "${var.project_name}-igw"
    Project = var.project_name
  }
}

# Table de routage : tout le trafic passe par l'IGW
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }

  tags = {
    Name    = "${var.project_name}-rt-public"
    Project = var.project_name
  }
}

# Association table de routage ↔ sous-réseau
resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

Security group

# Security group — règles de pare-feu
resource "aws_security_group" "web" {
  name        = "${var.project_name}-sg-web"
  description = "Autorise SSH et HTTP"
  vpc_id      = aws_vpc.main.id

  # SSH entrant
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "SSH"
  }

  # HTTP entrant
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "HTTP"
  }

  # Tout le trafic sortant autorisé
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name    = "${var.project_name}-sg-web"
    Project = var.project_name
  }
}

Instance EC2

# Instance EC2 avec Nginx installé au démarrage
resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = var.instance_type
  subnet_id     = aws_subnet.public.id

  vpc_security_group_ids = [aws_security_group.web.id]

  # Script exécuté au premier démarrage
  user_data = <<-EOF
    #!/bin/bash
    dnf update -y
    dnf install -y nginx
    systemctl enable nginx
    systemctl start nginx
    echo "<h1>Déployé avec Terraform — ${var.project_name}</h1>" > /usr/share/nginx/html/index.html
  EOF

  tags = {
    Name    = "${var.project_name}-ec2-web"
    Project = var.project_name
  }
}

# IP élastique — adresse IP fixe
resource "aws_eip" "web" {
  instance = aws_instance.web.id
  domain   = "vpc"

  tags = {
    Name    = "${var.project_name}-eip"
    Project = var.project_name
  }
}

Le fichier outputs.tf

Les outputs affichent les informations utiles une fois le déploiement terminé : l'IP publique et le DNS pour accéder au serveur.

# outputs.tf

output "public_ip" {
  description = "IP publique de l'instance EC2"
  value       = aws_eip.web.public_ip
}

output "public_dns" {
  description = "DNS public de l'instance EC2"
  value       = aws_instance.web.public_dns
}

output "web_url" {
  description = "URL du serveur web"
  value       = "http://${aws_eip.web.public_ip}"
}

Déploiement étape par étape

1. Initialisation

terraform init

Terraform télécharge le provider AWS et initialise le backend. Tu verras un message Terraform has been successfully initialized!.

2. Validation et plan

# Vérifier la syntaxe HCL
terraform validate

# Voir ce qui va être créé
terraform plan

Le plan devrait afficher 8 ressources à créer : vpc, subnet, internet gateway, route table, route table association, security group, instance EC2, elastic IP.

3. Application

terraform apply

Terraform affiche le plan et demande confirmation. Tape yes et valide. La création prend environ 1 à 2 minutes.

# Exemple de sortie après apply :
Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Outputs:

public_ip  = "15.237.42.110"
public_dns = "ec2-15-237-42-110.eu-west-3.compute.amazonaws.com"
web_url    = "http://15.237.42.110"

4. Vérification

# Ouvrir le serveur web dans le navigateur
curl http://$(terraform output -raw public_ip)

# Se connecter en SSH (si tu as une clé configurée)
ssh ec2-user@$(terraform output -raw public_ip)

# Vérifier l'état de Nginx sur le serveur
systemctl status nginx

Si le site web n'est pas accessible immédiatement, attends 30 secondes. Le script user_data s'exécute au démarrage de l'instance et prend quelques instants pour installer et lancer Nginx.

Nettoyage — terraform destroy

Une fois le projet terminé, détruis toutes les ressources pour ne pas générer de coûts :

terraform destroy

Terraform affiche la liste des ressources à détruire et demande confirmation. Tape yes. Toutes les ressources créées seront supprimées en moins d'une minute.

⚠️

Ne jamais supprimer manuellement des ressources depuis la console AWS si elles ont été créées par Terraform. Cela crée des incohérences dans le state. Toujours passer par terraform destroy ou terraform state rm.

Récapitulatif du module

Voici ce que tu as maîtrisé au cours de ce module Terraform :

📚

Leçon 01 — L'Infrastructure as Code : pourquoi coder son infra plutôt que cliquer dans une console.

Leçon 02 — Installer Terraform, écrire du HCL et comprendre le cycle init → plan → apply → destroy.

Leçon 03 — Les providers et les ressources : interagir avec AWS, Azure, GCP et des dizaines d'autres services.

Leçon 04 — Variables et outputs : rendre son code réutilisable et paramétrable.

Leçon 05 — Le state Terraform et les workspaces : gérer plusieurs environnements (dev, staging, prod) proprement.

Leçon 06 — Ce projet : déployer une infrastructure réseau + serveur complète sur AWS.

Prochaines étapes

Tu as les bases solides de Terraform. Voici où aller ensuite :

  • Modules Terraform — Crée des blocs réutilisables de ressources pour éviter la répétition. Le Terraform Registry propose des modules prêts à l'emploi pour tous les providers.
  • Terragrunt — Un wrapper autour de Terraform qui simplifie la gestion de multiples environnements et l'héritage de configuration.
  • Intégration CI/CD — Automatise tes déploiements Terraform avec GitHub Actions, GitLab CI ou Jenkins. terraform plan sur les PRs, terraform apply sur les merges vers main.
  • Terraform Cloud / HCP Terraform — Stocke ton state en remote, gère les runs dans une interface web, et collabore en équipe.
// À retenir
  • Structure en 4 fichiers : main.tf, variables.tf, outputs.tf, terraform.tfvars
  • Ordre réseau : VPC → subnet → internet gateway → route table → security group → EC2
  • Le user_data exécute un script shell au premier démarrage de l'instance
  • terraform output -raw <nom> récupère une valeur de sortie dans un script
  • Toujours terraform destroy après les tests — ne jamais supprimer manuellement depuis la console
  • Prochaines étapes : modules Terraform, Terragrunt, intégration CI/CD