Terraform : Construisez votre infrastructure comme du code
Découvrez comment automatiser la création et la gestion de vos ressources cloud avec Terraform, l'outil révolutionnaire qui transforme l'infrastructure en code lisible et versionnable. De zéro à votre premier déploiement en 30 minutes.
1. Qu'est-ce que Terraform et pourquoi c'est révolutionnaire
Terraform est un outil open-source créé par HashiCorp qui permet de décrire, planifier et créer une infrastructure cloud entière en utilisant du code. Imaginez que vous puissiez décrire votre maison (serveurs, base de données, réseaux) dans un fichier texte, et que simplement en exécutant une commande, cette maison se construise toute seule dans le cloud. C'est exactement ce que fait Terraform.
Avant Terraform, les administrateurs système devaient cliquer dans des interfaces web, créer manuellement chaque ressource, ce qui prenait du temps et engendrait des erreurs. Avec Terraform, vous écrivez votre infrastructure une seule fois, vous la versionnez comme du code, et vous pouvez la déployer partout identiquement. C'est une révolution appelée Infrastructure as Code (IaC).
Terraform fonctionne avec tous les grands fournisseurs cloud : AWS, Azure, Google Cloud, et même des services comme Kubernetes, GitHub ou Datadog. Un même fichier Terraform peut gérer des ressources sur plusieurs clouds simultanément, ce qui est extraordinaire pour la flexibilité.
Cas d'usage concrets :
- Une startup qui doit provisionner rapidement une infrastructure pour 10 000 utilisateurs
- Une entreprise qui doit répliquer son infrastructure identiquement dans plusieurs régions
- Un développeur qui veut créer son environnement de test en 5 minutes
# Exemple simple : créer un bucket S3 sur AWS
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "mon_bucket" {
bucket = "mon-bucket-unique-12345"
}
| Aspect | Avant Terraform | Avec Terraform |
|---|---|---|
| Déploiement | Clics manuels | Automatisé |
| Reproductibilité | Erreurs fréquentes | Identique partout |
| Versionning | Impossible | Possible avec Git |
| Temps de mise en place | 2-3 jours | 30 minutes |
| Documentation | Disparate | Dans le code même |
Astuce : Terraform ne crée rien jusqu'à ce que vous le lui demandiez. Il planifie d'abord les changements avec terraform plan, ce qui vous permet de vérifier avant d'appuyer sur le bouton.
⚠️ Attention : Terraform gère l'état de votre infrastructure dans un fichier .tfstate. Ce fichier contient des informations sensibles (mots de passe, clés d'accès). Jamais le committer sur GitHub sans chiffrement. Utilisez un backend distant (S3, Terraform Cloud) en production.
2. Les concepts fondamentaux : Providers, Resources et State
Pour utiliser Terraform efficacement, vous devez comprendre trois concepts clés : les providers, les resources et l'état.
Un provider est le lien entre Terraform et un service cloud ou un outil. C'est comme un traducteur. Quand vous voulez créer quelque chose sur AWS, vous dites à Terraform "j'utilise le provider AWS", et Terraform sait comment parler à AWS via ses APIs. Chaque provider expose différents types de ressources. Par exemple, le provider AWS expose aws_ec2_instance, aws_s3_bucket, aws_rds_instance, etc.
Une resource est une composant concrète de votre infrastructure. C'est un serveur, une base de données, un compte de stockage. Chaque ressource a des propriétés (appelées arguments) que vous configurez. Par exemple, une instance EC2 a une propriété instance_type qui définit sa puissance (t2.micro, t3.small, etc.).
L'état (state) est la mémoire de Terraform. Après avoir créé des ressources, Terraform enregistre l'état actuel de votre infrastructure dans un fichier terraform.tfstate. Quand vous lancez terraform apply à nouveau, Terraform compare l'état qu'il connaît avec ce que vous demandez dans le code, et applique uniquement les changements nécessaires.
# Configuration complète avec Provider et Resources
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# 1. PROVIDER - Configuration de la connexion
provider "aws" {
region = "eu-west-1"
}
# 2. RESOURCE - Serveur EC2
resource "aws_instance" "serveur_web" {
ami = "ami-0c55b159cbfafe1f0" # Image du système
instance_type = "t2.micro" # Puissance
tags = {
Name = "Mon Premier Serveur"
}
}
# 3. RESOURCE - Stockage S3
resource "aws_s3_bucket" "data_bucket" {
bucket = "mon-bucket-donnees-${data.aws_caller_identity.current.account_id}"
}
# Source de données - Récupère des informations existantes
data "aws_caller_identity" "current" {}
| Concept | Définition | Exemple |
|---|---|---|
| Provider | Connecteur vers un service | provider "aws" |
| Resource | Composant créé/géré | resource "aws_s3_bucket" |
| Data Source | Information récupérée | data "aws_availability_zones" |
| Variable | Valeur paramétrable | variable "environment" |
| Output | Valeur exportée | output "instance_ip" |
Astuce : Utilisez terraform state list pour voir toutes vos ressources gérées et terraform state show pour voir les détails d'une ressource spécifique. C'est utile pour déboguer.
⚠️ Attention : Le fichier d'état contient tout : les IDs, les propriétés, les données sensibles. Si vous supprimez le fichier d'état, Terraform perdra le suivi de vos ressources. Il créera des doublons lors du prochain apply. Toujours sauvegarder l'état !
3. Syntaxe Terraform : HCL et structure d'un projet
Terraform utilise un langage appelé HCL (HashiCorp Configuration Language). HCL est volontairement simple et lisible, même pour les non-programmeurs. C'est du texte structuré avec des accolades, comme JSON mais plus lisible.
La structure typique d'un projet Terraform comprend plusieurs fichiers :
main.tf: Les principales ressourcesvariables.tf: Les variables d'entréeoutputs.tf: Les valeurs à exporterterraform.tfvars: Les valeurs des variablesbackend.tf: Configuration du stockage d'état
Chaque fichier .tf est automatiquement lu et interprété. Terraform fusionne tous les fichiers comme s'ils étaient un seul.
Les variables permettent de paramétrer votre infrastructure. Au lieu de coder en dur instance_type = "t2.micro", vous créez une variable instance_type et la passez en paramètre. Cela rend votre code réutilisable : même configuration pour dev, staging et production.
Les outputs exposent des informations importantes après le déploiement. Par exemple, après avoir créé un serveur, vous voudrez connaître son adresse IP publique. Les outputs l'affichent dans la console.
# ===== variables.tf =====
variable "environment" {
description = "Environnement de déploiement"
type = string
default = "dev"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment doit être dev, staging ou prod."
}
}
variable "instance_type" {
description = "Type d'instance EC2"
type = string
default = "t2.micro"
}
variable "tags" {
description = "Tags à appliquer"
type = map(string)
default = {
Team = "DevOps"
Cost = "Project-A"
}
}
# ===== main.tf =====
resource "aws_instance" "app_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type
tags = merge(
var.tags,
{
Name = "AppServer-${var.environment}"
Environment = var.environment
}
)
}
# ===== outputs.tf =====
output "instance_public_ip" {
description = "Adresse IP publique du serveur"
value = aws_instance.app_server.public_ip
}
output "instance_id" {
description = "ID de l'instance"
value = aws_instance.app_server.id
}
# ===== terraform.tfvars =====
environment = "prod"
instance_type = "t3.small"
| Élément | Type | Utilité | Exemple |
|---|---|---|---|
| Variable | Input | Paramètres | var.environment |
| Local | Interne | Calculs | local.subnet_count |
| Output | Export | Résultats | aws_instance.id |
| Data Source | Lecture | Infos externes | data.aws_availability_zones |
| Resource | Création | Ressources | resource "aws_s3_bucket" |
Astuce : Utilisez des local pour des calculs simples et réduire la répétition. Par exemple, au lieu de répéter le préfixe du nom partout, définissez local.project_prefix = "${var.project}-${var.environment}".
⚠️ Attention : Les variables par défaut apparaissent en clair dans le code. Pour les secrets (mots de passe, clés API), utilisez toujours un gestionnaire externe comme AWS Secrets Manager ou une variable d'environnement TF_VAR_.
4. Workflow Terraform : init, plan, apply et destroy
Le workflow Terraform suit toujours le même pattern en 4 étapes. C'est simple, prévisible et sûr.
Étape 1 : terraform init
C'est l'initialisation. Vous la lancez une seule fois au début d'un projet (ou quand vous changez de provider). Terraform télécharge les providers nécessaires et met en place le backend pour l'état. C'est comme "npm install" pour Terraform.
Étape 2 : terraform plan
Terraform compare l'état actuel avec vos fichiers .tf et vous montre EXACTEMENT ce qui va changer. Vous verrez des lignes avec + (création), - (suppression) ou ~ (modification). C'est un aperçu sans risque. Rien n'est créé à cette étape.
Étape 3 : terraform apply
Vous avez validé le plan et êtes satisfait ? Lancez apply. Terraform crée/modifie/supprime les ressources pour atteindre l'état désiré. Terraform demandera une confirmation avant d'agir.
Étape 4 : terraform destroy (optionnel)
Besoin de tout nettoyer ? Destroy supprime toutes les ressources gérées par Terraform. Utile pour économiser de l'argent en dev ou en testing.
# ===== Workflow complet =====
# 1. Initialisation (une seule fois)
terraform init
# Output :
# - Initializing the backend...
# - Downloading aws provider...
# - Terraform has been successfully configured!
# 2. Vérifier les changements (sans risque)
terraform plan
# Output :
# Terraform will perform the following actions:
#
# + aws_instance.app_server will be created
# + aws_security_group.allow_http will be created
#
# Plan: 2 to add, 0 to change, 0 to destroy.
# Sauvegarder le plan dans un fichier pour l'audit
terraform plan -out=tfplan
# 3. Appliquer les changements
terraform apply tfplan
# Output :
# aws_security_group.allow_http: Creating...
# aws_security_group.allow_http: Creation complete after 1s [id=sg-12345678]
# aws_instance.app_server: Creating...
# aws_instance.app_server: Creation complete after 15s [id=i-0123456789abcdef]
#
# Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
# 4. Voir l'état actuel
terraform show
# 5. Exporter les outputs
terraform output
# instance_public_ip = "52.123.45.67"
# instance_id = "i-0123456789abcdef"
# 6. Nettoyer (détruire tout)
terraform destroy
# Output :
# Plan: 0 to add, 0 to change, 2 to destroy.
# Destroy complete! Resources: 2 destroyed.
| Commande | Moment | Risque | Résultat |
|---|---|---|---|
terraform init |
Au début | Aucun | Prêt à utiliser |
terraform plan |
Avant apply | Aucun | Aperçu des changements |
terraform apply |
Quand validé | ⚠️ Crée des ressources | Infrastructure créée |
terraform destroy |
Nettoyage | ⚠️ Supprime tout | Infrastructure détruite |
Astuce : Toujours lancer terraform plan avant apply. Sauvegardez même le plan avec -out pour l'audit et la traçabilité. Cela prouve exactement ce qui a été appliqué.
⚠️ Attention : terraform destroy supprime TOUT. Pas de corbeille. Si vous avez une base de données importante, elle sera effacée définitivement. Toujours vérifier le plan avant de valider destroy.
5. Bonnes pratiques et structure d'un projet professionnel
Un projet Terraform professionnel ne c'est pas juste un dossier avec des fichiers .tf. C'est organisé, documenté, versionné et sécurisé. Voici comment structurer un projet pour pouvoir le maintenir et le partager en équipe.
Organisation en modules : Comme on divise un grand programme en fonctions, on divise un grand projet Terraform en modules. Un module est un dossier réutilisable contenant des ressources liées. Par exemple, un module network pour créer VPC, subnets, routeurs, et un module database pour créer les bases de données. Cela rend le code plus lisible et testable.
Environnements séparés : Dev, staging et production ne doivent pas partager le même state. Utilisez des workspaces ou des dossiers séparés. Un bug en dev ne doit jamais affecter la prod.
Backend distant : Stockez l'état dans S3, Terraform Cloud ou un service équivalent. Cela permet à une équipe de collaborer sans conflits de fichiers.
Versionning et CI/CD : Stockez votre Terraform sur Git. Utilisez des pipelines (GitHub Actions, GitLab CI) pour valider automatiquement vos fichiers, lancer terraform plan et même approuver les deployments.
Documentation : Documentez les variables, les outputs et pourquoi vous avez certaines configurations. Un commentaire aujourd'hui économise des heures de débogage demain.
# ===== Structure de projet professionnel =====
#
# mon-infra/
# ├── README.md # Guide du projet
# ├── .gitignore # Exclure fichiers sensibles
# ├── terraform.tf # Version et provider
# ├── environments/
# │ ├── dev/
# │ │ ├── main.tf
# │ │ ├── variables.tf
# │ │ ├── terraform.tfvars
# │ │ └── backend.tf
# │ ├── staging/
# │ └── prod/
# └── modules/
# ├── network/
# │ ├── main.tf
# │ ├── variables.tf
# │ ├── outputs.tf
# │ └── README.md
# ├── database/
# └── compute/
# ===== Utiliser un module =====
module "network" {
source = "./modules/network"
vpc_cidr = "10.0.0.0/16"
environment = var.environment
availability_zones = ["eu-west-1a", "eu-west-1b"]
}
resource "aws_instance" "app" {
ami = var.ami_id
instance_type = var.instance_type
subnet_id = module.network.public_subnet_id
depends_on = [module.network]
}
# ===== Backend distant pour la collaboration =====
terraform {
backend "s3" {
bucket = "mon-terraform-state"
key = "prod/terraform.tfstate"
region = "eu-west-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
# ===== Workspace pour gérer les environnements =====
# Créer un workspace pour staging
# terraform workspace new staging
# Lister les workspaces
# terraform workspace list
# Changer de workspace
# terraform workspace select staging
| Pratique | Importance | Bénéfice |
|---|---|---|
| Modules réutilisables | Haute | Moins de code, maintenance facile |
| Backend distant | Haute | Collaboration, sécurité |
| Versionning sur Git | Haute | Historique, rollback, audit |
| CI/CD automation | Moyenne | Validation avant deploy |
| Documentation | Moyenne | Onboarding rapide |
Astuce : Utilisez terraform fmt pour formater automatiquement votre code HCL. C'est comme prettier ou black. Cela garantit un style cohérent en équipe.
⚠️ Attention : Jamais committer .tfstate ou terraform.tfvars sur Git. Même si le repo est privé, ces fichiers contiennent des secrets. Ajoutez-les à .gitignore. Utilisez des variables d'environnement ou Terraform Cloud pour les secrets.