Introduction
Terraform vous permet de :
- Decrire votre infra en code HCL (HashiCorp Configuration Language)
- Provisionner serveurs, reseau, DNS, certificats sur tous les clouds
- Gerer le state (qui possede quoi)
- Planifier les changements avant application
- Versionner votre infra dans Git
Cas d'usage : creer 100 VPS identiques, monter un cluster K8s sur AWS, gerer DNS Cloudflare en code, etc.
Note : depuis 2023, Terraform est sous licence BSL (commerciale). Le fork community OpenTofu garde la licence open-source MPL. Ce tuto utilise terraform mais tout fonctionne pareil avec tofu.
Prerequis
- VPS Linux ou poste de travail Linux / macOS / Windows
- Compte sur un cloud provider (AWS, Hetzner, OVH, etc.)
- Acces root (pour install)
Etape 1 : Installation
Debian / Ubuntu
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
terraform version
Ou OpenTofu
curl -fsSL https://get.opentofu.org/install-opentofu.sh | sudo sh -s -- --install-method deb
tofu version
Etape 2 : Premier project (Hetzner Cloud)
Creez un dossier :
mkdir ~/infra-hetzner && cd ~/infra-hetzner
main.tf :
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.45"
}
}
}
provider "hcloud" {
token = var.hcloud_token
}
variable "hcloud_token" {
type = string
sensitive = true
}
resource "hcloud_server" "web1" {
name = "web1"
image = "debian-12"
server_type = "cx22"
location = "fsn1"
ssh_keys = [hcloud_ssh_key.default.id]
}
resource "hcloud_ssh_key" "default" {
name = "ma-cle"
public_key = file("~/.ssh/id_ed25519.pub")
}
output "server_ip" {
value = hcloud_server.web1.ipv4_address
}
Etape 3 : Initialiser
terraform init
Telecharge le provider Hetzner. Cree .terraform/ et .terraform.lock.hcl.
Etape 4 : Plan
export TF_VAR_hcloud_token="votre-token-hetzner"
terraform plan
Affiche les changements (creations, modifications, destructions). Lisez toujours le plan attentivement avant d'apply.
Etape 5 : Apply
terraform apply
Tapez yes pour confirmer. Terraform cree le serveur Hetzner. A la fin :
Outputs:
server_ip = "5.78.123.45"
SSH dessus :
ssh [email protected]
Etape 6 : State
Le state est dans terraform.tfstate. Il contient l'etat actuel de votre infra (ressources, IDs, attributs).
⚠️ Ne le commitez jamais dans Git. Mettez-le dans .gitignore.
echo "*.tfstate*" >> .gitignore
echo ".terraform/" >> .gitignore
Pour le travail en equipe, utilisez un backend distant.
Etape 7 : Backend distant (S3)
backend.tf :
terraform {
backend "s3" {
bucket = "monequipe-terraform-state"
key = "infra-hetzner/terraform.tfstate"
region = "eu-west-3"
encrypt = true
}
}
terraform init -migrate-state
State est maintenant sur S3, partage entre membres de l'equipe. Utilisez DynamoDB pour le locking (eviter applies concurrents).
Alternatives a S3 : Terraform Cloud (managed), Scalr, Spacelift, ou backend HTTP custom.
Etape 8 : Variables et environments
variables.tf :
variable "environment" {
type = string
default = "dev"
}
variable "server_type" {
type = string
default = "cx22"
}
locals {
common_tags = {
Environment = var.environment
ManagedBy = "terraform"
}
}
Utilisation :
resource "hcloud_server" "web" {
name = "${var.environment}-web"
server_type = var.server_type
labels = local.common_tags
}
Variables via fichier .tfvars :
prod.tfvars :
environment = "prod"
server_type = "ccx33"
terraform apply -var-file=prod.tfvars
Etape 9 : Modules
Encapsulez du code reutilisable dans un module :
modules/
webapp/
main.tf
variables.tf
outputs.tf
modules/webapp/main.tf :
resource "hcloud_server" "web" {
name = var.name
image = "debian-12"
server_type = var.server_type
location = var.location
ssh_keys = var.ssh_keys
}
Utilisation :
module "web1" {
source = "./modules/webapp"
name = "web1"
server_type = "cx22"
location = "fsn1"
ssh_keys = [hcloud_ssh_key.default.id]
}
module "web2" {
source = "./modules/webapp"
name = "web2"
server_type = "cx32"
location = "nbg1"
ssh_keys = [hcloud_ssh_key.default.id]
}
Ou utilisez des modules communautaires : https://registry.terraform.io
Etape 10 : Provisioning (cloud-init)
Pour configurer le serveur a sa creation :
resource "hcloud_server" "web" {
name = "web"
image = "debian-12"
server_type = "cx22"
location = "fsn1"
user_data = <<-EOT
#cloud-config
package_update: true
packages:
- nginx
- certbot
runcmd:
- systemctl enable nginx
- echo "Hello from terraform" > /var/www/html/index.html
EOT
}
Pour des configurations complexes, deleguez a Ansible apres provisioning Terraform.
Etape 11 : Destroy
terraform destroy
⚠️ Detruit toute l'infra geree par ce state. Faites attention.
Detruire une seule ressource :
terraform destroy -target=hcloud_server.web1
Etape 12 : Workflow pro
Le workflow standard en equipe :
# 1. Pull la derniere version
git pull
# 2. Format et validate
terraform fmt -recursive
terraform validate
# 3. Plan
terraform plan -out=tfplan
# 4. Review le plan (ou code review via PR)
terraform show tfplan
# 5. Apply le plan exact
terraform apply tfplan
# 6. Commit + push
git add . && git commit -m "Ajout web1" && git push
En CI, utilisez Atlantis ou Terraform Cloud pour automatiser les plan + apply via PR.
Depannage
"Error: Provider not found"
terraform init -upgrade
State lock
Si un autre terraform tourne ou a crashe :
terraform force-unlock LOCK_ID
Verifiez d'abord que personne ne fait apply en parallele.
"resource already exists"
Vous avez cree une ressource hors terraform. Importez-la :
terraform import hcloud_server.web1 12345
Drift (ressource modifiee a la main)
terraform plan
Affiche le drift. apply re-aligne. Ou ajustez votre code pour matcher la realite.
"Provider produced inconsistent final plan"
Bug du provider. Mettez a jour :
terraform init -upgrade
Commandes utiles
terraform init # init du project
terraform plan # voir les changements
terraform apply # appliquer
terraform destroy # tout detruire
terraform fmt -recursive # formatter
terraform validate # valider syntaxe
terraform show # voir le state
terraform state list # lister les ressources
terraform state show <resource> # voir le detail
terraform state rm <resource> # retirer du state (sans destroy)
terraform state mv <from> <to> # renommer dans le state
terraform import <resource> <id> # importer existing
terraform output # voir les outputs
terraform output -json # json
terraform workspace list # workspaces (envs paralleles)
terraform workspace new staging
terraform workspace select staging
Conclusion
Terraform vous donne :
- Infrastructure declarative et versionnee
- Multi-cloud
- State management pour le travail en equipe
- Modules reutilisables
Pour aller plus loin :
- Utilisez Atlantis ou Terraform Cloud pour le workflow CI/CD
- Combinez avec Ansible pour configurer apres provisioning
- Pour Kubernetes, regardez Pulumi ou Crossplane (k8s-native)
- Pour rester open-source, migrez vers OpenTofu
Ressources
- Documentation officielle : https://developer.hashicorp.com/terraform
- Registry providers : https://registry.terraform.io
- OpenTofu : https://opentofu.org
- Atlantis : https://www.runatlantis.io


















