Demande d'informations
DevOps

Terraform : à quoi ça sert ? Premier projet pas à pas

📅 15 octobre 2025⏱️ 9 min de lecture

Terraform est l'outil d'Infrastructure as Code (IaC) le plus populaire. Il permet de créer, modifier et versionner votre infrastructure cloud de manière déclarative. Fini les clics dans la console AWS ou Azure : tout est dans le code.

Pourquoi Terraform ?

Le problème sans IaC

Imaginez : vous configurez manuellement 50 serveurs, des load balancers, des bases de données... Un mois plus tard, vous devez recréer le même environnement. Bonne chance pour vous souvenir de chaque paramètre !

La solution Terraform

  • Déclaratif : vous décrivez l'état souhaité, Terraform s'occupe du reste
  • Versionné : votre infrastructure est dans Git, avec historique
  • Reproductible : créez 10 environnements identiques en une commande
  • Multi-cloud : AWS, Azure, GCP avec la même syntaxe

Les concepts de base

Provider

Le provider est le "connecteur" vers un cloud ou service. Azure, AWS, Kubernetes, GitHub... il existe des centaines de providers.

Resource

Une resource est un élément d'infrastructure : VM, réseau, base de données, etc.

State

Terraform maintient un fichier "state" qui garde en mémoire l'état actuel de votre infrastructure.

Premier projet : une VM Azure

Créons ensemble une machine virtuelle sur Azure.

1. Installer Terraform

# macOS
brew install terraform

# Windows (avec Chocolatey)
choco install terraform

# Vérifier l'installation
terraform --version

2. Créer le fichier main.tf

# Configuration du provider Azure
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
  }
}

provider "azurerm" {
  features {}
}

# Resource Group
resource "azurerm_resource_group" "example" {
  name     = "rg-terraform-demo"
  location = "West Europe"
}

# Virtual Network
resource "azurerm_virtual_network" "example" {
  name                = "vnet-demo"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

# Subnet
resource "azurerm_subnet" "example" {
  name                 = "subnet-demo"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]
}

# Network Security Group
resource "azurerm_network_security_group" "example" {
  name                = "nsg-demo"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  security_rule {
    name                       = "SSH"
    priority                   = 1001
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "22"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

# Public IP
resource "azurerm_public_ip" "example" {
  name                = "pip-demo"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  allocation_method   = "Static"
  sku                 = "Standard"
}

# Network Interface
resource "azurerm_network_interface" "example" {
  name                = "nic-demo"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.example.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.example.id
  }
}

# Associate NSG with NIC
resource "azurerm_network_interface_security_group_association" "example" {
  network_interface_id      = azurerm_network_interface.example.id
  network_security_group_id = azurerm_network_security_group.example.id
}

# Virtual Machine
resource "azurerm_linux_virtual_machine" "example" {
  name                = "vm-demo"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  size                = "Standard_B1s"
  admin_username      = "azureuser"
  
  network_interface_ids = [
    azurerm_network_interface.example.id,
  ]

  admin_ssh_key {
    username   = "azureuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }
}

# Output: Public IP address
output "public_ip_address" {
  value = azurerm_public_ip.example.ip_address
}

3. Exécuter Terraform

# Initialiser (télécharge le provider)
terraform init

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

# Créer l'infrastructure
terraform apply

# Détruire l'infrastructure
terraform destroy

🏗️ Devenez expert Terraform

Apprenez à gérer des infrastructures cloud complètes avec notre formation DevOps.

Voir le programme →

Bonnes pratiques Terraform

  • Modules : réutilisez du code avec des modules
  • Variables : ne hardcodez jamais les valeurs
  • Remote state : stockez le state dans Azure Blob ou S3
  • Workspaces : gérez dev/staging/prod avec le même code
  • Formatting : utilisez terraform fmt

Terraform vs Ansible vs Bicep

  • Terraform : Infrastructure as Code multi-cloud
  • Ansible : Configuration management (installer des logiciels)
  • Bicep : IaC natif Azure (alternative à Terraform pour Azure only)

En pratique, Terraform + Ansible sont souvent utilisés ensemble : Terraform crée les VMs, Ansible les configure.

Conclusion

Terraform est un outil incontournable pour tout DevOps. Commencez par des projets simples, puis progressez vers des architectures plus complexes avec des modules et du remote state.