skip to content

Recherche

Terraform

Déployer ses ressources avec l'outil IaC Terraform !

Terraform est un outil d’infrastructure as code pour créer, modifier et versionner l’infrastructure de manière sécurisée et efficace sur tous les providers cloud.

🚀 Installation

📌 Plateforme🧠 Commande
🐧 Ubuntu/Debianwget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
🎩 CentOS/RHELsudo yum install -y yum-utils && sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
🍺 macOSbrew tap hashicorp/tap && brew install terraform
🪟 Windowschoco install terraform
📦 Binary directTélécharger depuis releases.hashicorp.com

⚙️ Commandes essentielles

📌 Action🧠 Commande💡 Description
🏁 Initialiserterraform initInitialise le projet et télécharge les providers
📋 Planifierterraform planAffiche les changements qui seront appliqués
Appliquerterraform applyApplique les changements à l’infrastructure
💥 Détruireterraform destroySupprime toutes les ressources gérées
🔍 Validerterraform validateVérifie la syntaxe des fichiers
📊 Étatterraform showAffiche l’état actuel
🔄 Refreshterraform refreshMet à jour l’état avec la réalité

📊 Gestion de l’état

📌 Action🧠 Commande
📋 Lister ressourcesterraform state list
👁️ Voir une ressourceterraform state show aws_instance.web
🔄 Importer ressourceterraform import aws_instance.web i-1234567890abcdef0
🗑️ Supprimer du stateterraform state rm aws_instance.web
📍 Déplacer ressourceterraform state mv aws_instance.web aws_instance.web2
💾 Pull stateterraform state pull
📤 Push stateterraform state push terraform.tfstate

🎯 Options utiles

📌 Option🧠 Exemple💡 Usage
🎯 Targetterraform apply -target=aws_instance.webApplique seulement à une ressource
🔄 Auto-approveterraform apply -auto-approvePas de confirmation interactive
📁 Var-fileterraform apply -var-file="prod.tfvars"Utilise un fichier de variables
🔧 Varterraform apply -var="instance_count=3"Passe une variable
💾 Stateterraform apply -state=custom.tfstateUtilise un fichier state custom
🗂️ Plan fileterraform plan -out=plan.outSauvegarde le plan

📝 Structure de fichiers

Organisation recommandée

terraform-project/
├── main.tf              # Configuration principale
├── variables.tf         # Déclaration des variables
├── outputs.tf          # Sorties
├── terraform.tfvars    # Valeurs des variables
├── versions.tf         # Versions providers
└── modules/            # Modules réutilisables
    ├── vpc/
    ├── ec2/
    └── rds/

Fichier main.tf exemple

terraform {
  required_version = ">= 1.0"
  required_providers {
    vsphere = {
      source  = "hashicorp/vsphere"
      version = "~> 2.0"
    }
  }
}
 
provider "vsphere" {
  user           = var.vsphere_user
  password       = var.vsphere_password
  vsphere_server = var.vsphere_server
  
  # Si certificat auto-signé
  allow_unverified_ssl = true
}
 
# Datasources pour récupérer les infos vSphere
data "vsphere_datacenter" "datacenter" {
  name = "Datacenter"
}
 
data "vsphere_datastore" "datastore" {
  name          = "datastore1"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}
 
data "vsphere_compute_cluster" "cluster" {
  name          = "cluster1"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}
 
data "vsphere_network" "network" {
  name          = "VM Network"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}
 
data "vsphere_virtual_machine" "template" {
  name          = "ubuntu-20.04-template"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}
 
# VM
resource "vsphere_virtual_machine" "web" {
  name             = "${var.vm_name}-web"
  resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
  datastore_id     = data.vsphere_datastore.datastore.id
  
  num_cpus = 2
  memory   = 4096
  guest_id = data.vsphere_virtual_machine.template.guest_id
  
  scsi_type = data.vsphere_virtual_machine.template.scsi_type
  
  network_interface {
    network_id   = data.vsphere_network.network.id
    adapter_type = data.vsphere_virtual_machine.template.network_interface_types[0]
  }
  
  disk {
    label            = "disk0"
    size             = data.vsphere_virtual_machine.template.disks.0.size
    eagerly_scrub    = data.vsphere_virtual_machine.template.disks.0.eagerly_scrub
    thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
  }
  
  clone {
    template_uuid = data.vsphere_virtual_machine.template.id
    
    customize {
      linux_options {
        host_name = "${var.vm_name}-web"
        domain    = "example.com"
      }
      
      network_interface {
        ipv4_address = "192.168.1.100"
        ipv4_netmask = 24
      }
      
      ipv4_gateway = "192.168.1.1"
      dns_server_list = ["8.8.8.8", "8.8.4.4"]
    }
  }
}

Variables (variables.tf)

variable "vsphere_server" {
  description = "Serveur vCenter"
  type        = string
  default     = "vcenter.example.com"
}
 
variable "vsphere_user" {
  description = "Utilisateur vSphere"
  type        = string
}
 
variable "vsphere_password" {
  description = "Mot de passe vSphere"
  type        = string
  sensitive   = true
}
 
variable "vm_name" {
  description = "Nom de base des VMs"
  type        = string
  default     = "terraform-vm"
}
 
variable "vm_count" {
  description = "Nombre de VMs à créer"
  type        = number
  default     = 1
}

Outputs (outputs.tf)

output "vm_name" {
  description = "Nom de la VM créée"
  value       = vsphere_virtual_machine.web.name
}
 
output "vm_ip" {
  description = "IP de la VM"
  value       = vsphere_virtual_machine.web.default_ip_address
}
 
output "vm_uuid" {
  description = "UUID de la VM"
  value       = vsphere_virtual_machine.web.uuid
  sensitive   = false
}

📦 Modules

Créer un module

# modules/vm/main.tf
resource "vsphere_virtual_machine" "this" {
  name             = var.vm_name
  resource_pool_id = var.resource_pool_id
  datastore_id     = var.datastore_id
  
  num_cpus = var.num_cpus
  memory   = var.memory
  guest_id = var.guest_id
  
  network_interface {
    network_id = var.network_id
  }
  
  disk {
    label = "disk0"
    size  = var.disk_size
  }
  
  clone {
    template_uuid = var.template_uuid
    
    customize {
      linux_options {
        host_name = var.vm_name
        domain    = var.domain
      }
      
      network_interface {
        ipv4_address = var.ip_address
        ipv4_netmask = 24
      }
      
      ipv4_gateway = var.gateway
    }
  }
}
 
# modules/vm/variables.tf
variable "vm_name" {
  description = "Nom de la VM"
  type        = string
}
 
variable "num_cpus" {
  description = "Nombre de CPUs"
  type        = number
  default     = 2
}
 
variable "memory" {
  description = "Mémoire en MB"
  type        = number
  default     = 4096
}

Utiliser un module

module "web_server" {
  source = "./modules/vm"
  
  vm_name          = "web-01"
  resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
  datastore_id     = data.vsphere_datastore.datastore.id
  network_id       = data.vsphere_network.network.id
  template_uuid    = data.vsphere_virtual_machine.template.id
  guest_id         = data.vsphere_virtual_machine.template.guest_id
  
  num_cpus    = 4
  memory      = 8192
  ip_address  = "192.168.1.101"
  gateway     = "192.168.1.1"
  domain      = "example.com"
}
 
# Référencer une sortie de module
output "web_server_ip" {
  value = module.web_server.ip_address
}

🎯 Bonnes pratiques

📌 Pratique💡 Description
📁 OrganisationSéparer par environnement et services
🏷️ TaggingUtiliser des tags cohérents partout
🔒 État distantToujours utiliser un backend distant
🔐 SecretsNe jamais hardcoder les secrets
📝 DocumentationCommenter et documenter le code
🧪 ValidationTester avec terraform plan
📦 ModulesRéutiliser avec des modules
🔄 VersioningVerrouiller les versions providers

🔍 Debugging & Troubleshooting

📌 Debug🧠 Commande
🐛 Mode debugTF_LOG=DEBUG terraform apply
📝 Logs détaillésTF_LOG=TRACE terraform plan
🔍 Graphterraform graph | dot -Tpng > graph.png
✅ Format checkterraform fmt -check -diff
🔧 Format autoterraform fmt -recursive