Infrastructure as Code avec Terraform : de la gestion manuelle à la gestion automatisée du cloud
Les organisations utilisant l'Infrastructure as Code (IaC) fournissent des environnements 90 % plus rapidement et subissent 60 % moins de pannes liées à la configuration que celles qui gèrent l'infrastructure manuellement. Terraform est devenu l'outil IaC dominant, avec plus de 3 000 fournisseurs prenant en charge toutes les principales plates-formes cloud et services SaaS.
Ce guide couvre l'utilisation pratique de Terraform pour les applications Web, les systèmes ERP et les plates-formes de commerce électronique, de la première définition de ressources aux déploiements multi-environnements de production.
Points clés à retenir
- Terraform rend les modifications d'infrastructure révisables, testables et réversibles grâce au contrôle de version
- La gestion de l'état à distance évite les conflits lorsque plusieurs ingénieurs modifient l'infrastructure
- Les modules encapsulent des modèles réutilisables, réduisant la configuration de centaines de lignes à quelques paramètres
- L'intégration Terraform Cloud ou CI/CD applique la discipline de planification avant application pour des changements sûrs
Pourquoi Terraform pour les PME
Le problème de l'infrastructure manuelle
Sans IaC, vos connaissances en infrastructure résident dans :
- Chemins de clics de la console AWS que personne n'a documentés
- Des commandes SSH exécutées il y a des mois et dont personne ne se souvient
- Fichiers de configuration édités directement sur les serveurs
- Le modèle mental d'un ingénieur sur "le fonctionnement du réseau"
Avec Terraform, votre infrastructure réside dans Git. Chaque changement est une pull request. Chaque déploiement est reproductible. Chaque ingénieur peut comprendre la situation dans son ensemble.
Concepts de base
| Concepts | Descriptif |
|---|---|
| Fournisseur | Plugin qui s'interface avec une plateforme cloud (AWS, GCP, Azure, Cloudflare) |
| Ressource | Un seul composant d'infrastructure (instance EC2, base de données RDS, bucket S3) |
| Source de données | Référence en lecture seule à l'infrastructure existante |
| Variables | Paramètre d'entrée pour configuration réutilisable |
| Sortie | Valeur exportée à partir d'une configuration Terraform |
| État | Enregistrement de ce que Terraform gère et de ses attributs actuels |
| Module | Groupe de ressources réutilisable avec une interface définie |
Première configuration de Terraform
AWS VPC et EC2 pour une application Web
# providers.tf
terraform {
required_version = ">= 1.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "ecosire-terraform-state"
key = "production/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
provider "aws" {
region = var.aws_region
}
# variables.tf
variable "aws_region" {
type = string
default = "us-east-1"
}
variable "environment" {
type = string
default = "production"
}
variable "instance_type" {
type = string
default = "t3.large"
}
# main.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.environment}-vpc"
Environment = var.environment
ManagedBy = "terraform"
}
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 1}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.environment}-public-${count.index + 1}"
}
}
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = aws_subnet.public[0].id
vpc_security_group_ids = [aws_security_group.app.id]
key_name = aws_key_pair.deploy.key_name
root_block_device {
volume_size = 50
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-app"
Environment = var.environment
}
}
resource "aws_db_instance" "postgres" {
identifier = "${var.environment}-db"
engine = "postgres"
engine_version = "17"
instance_class = "db.t3.medium"
allocated_storage = 50
max_allocated_storage = 200
storage_encrypted = true
db_name = "ecosire"
username = "app"
password = var.db_password
vpc_security_group_ids = [aws_security_group.db.id]
db_subnet_group_name = aws_db_subnet_group.main.name
backup_retention_period = 7
backup_window = "03:00-04:00"
maintenance_window = "sun:04:00-sun:05:00"
skip_final_snapshot = false
final_snapshot_identifier = "${var.environment}-db-final"
tags = {
Environment = var.environment
}
}
Modules pour une infrastructure réutilisable
Création d'un module d'application Web
# modules/web-app/main.tf
variable "name" {
type = string
}
variable "environment" {
type = string
}
variable "instance_type" {
type = string
default = "t3.medium"
}
variable "vpc_id" {
type = string
}
variable "subnet_ids" {
type = list(string)
}
resource "aws_lb" "app" {
name = "${var.name}-${var.environment}-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = var.subnet_ids
}
resource "aws_lb_target_group" "app" {
name = "${var.name}-${var.environment}-tg"
port = 3000
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
path = "/health"
healthy_threshold = 2
unhealthy_threshold = 3
interval = 30
}
}
resource "aws_autoscaling_group" "app" {
name = "${var.name}-${var.environment}-asg"
min_size = 2
max_size = 10
desired_capacity = 2
vpc_zone_identifier = var.subnet_ids
target_group_arns = [aws_lb_target_group.app.arn]
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
tag {
key = "Name"
value = "${var.name}-${var.environment}"
propagate_at_launch = true
}
}
output "alb_dns_name" {
value = aws_lb.app.dns_name
}
Utilisation du module
# environments/production/main.tf
module "web" {
source = "../../modules/web-app"
name = "ecosire-web"
environment = "production"
instance_type = "t3.large"
vpc_id = module.network.vpc_id
subnet_ids = module.network.public_subnet_ids
}
module "api" {
source = "../../modules/web-app"
name = "ecosire-api"
environment = "production"
instance_type = "t3.large"
vpc_id = module.network.vpc_id
subnet_ids = module.network.public_subnet_ids
}
Gestion de l'état
État distant avec S3
# Bootstrap: create the state bucket and DynamoDB table manually or with a separate config
resource "aws_s3_bucket" "terraform_state" {
bucket = "ecosire-terraform-state"
lifecycle {
prevent_destroy = true
}
}
resource "aws_s3_bucket_versioning" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_dynamodb_table" "terraform_locks" {
name = "terraform-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
Le verrouillage de l'état via DynamoDB empêche deux ingénieurs d'exécuter terraform apply simultanément, ce qui pourrait corrompre l'état.
Sécurité des fichiers d'état
Le fichier d'état Terraform contient des informations sensibles, notamment des mots de passe de base de données, des clés API et des ID de ressources. Protégez-le :
- Chiffrement au repos : gestion des versions du bucket S3 + chiffrement côté serveur
- Chiffrer en transit : HTTPS uniquement pour l'accès à l'état
- Restreindre l'accès : politiques IAM limitant les personnes pouvant lire/écrire l'état
- Ne jamais s'engager sur Git : les fichiers d'état ne doivent jamais être sous contrôle de version
- Activer la gestion des versions : la gestion des versions S3 permet la récupération à partir d'un état corrompu
Intégration CI/CD
Pipeline Terraform d'actions GitHub
name: Terraform
on:
pull_request:
paths: ['infrastructure/**']
push:
branches: [main]
paths: ['infrastructure/**']
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform init
working-directory: infrastructure/environments/production
- name: Terraform Plan
run: terraform plan -out=tfplan
working-directory: infrastructure/environments/production
- name: Comment PR with plan
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const plan = require('fs').readFileSync('infrastructure/environments/production/tfplan.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Terraform Plan\n\`\`\`\n${plan}\n\`\`\``
});
apply:
needs: plan
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Apply
run: terraform apply -auto-approve
working-directory: infrastructure/environments/production
Stratégie multi-environnements
| Environnement | Objectif | Tailles des instances | Objectif de coût |
|---|---|---|---|
| Développement | Test des fonctionnalités | t3.micro / t3.petit | <100$/mois |
| Mise en scène | Validation pré-production | Production de miroirs (plus petits) | ~30% de la production |
| Fabrication | Trafic en direct | Adapté à la charge | Optimisé |
Utilisez des espaces de travail Terraform ou des répertoires distincts par environnement :
infrastructure/
modules/
web-app/
database/
network/
environments/
development/
main.tf
terraform.tfvars
staging/
main.tf
terraform.tfvars
production/
main.tf
terraform.tfvars
Questions fréquemment posées
Terraform ou Pulumi --- que devons-nous choisir ?
Terraform si votre équipe comprend des ingénieurs d'exploitation qui préfèrent la configuration déclarative. Pulumi si votre équipe est composée de nombreux développeurs et préfère écrire une infrastructure en TypeScript ou Python. Terraform dispose d'un écosystème plus vaste et de plus de modules communautaires. Pulumi a une courbe d'apprentissage initiale plus raide mais est plus flexible pour la logique complexe.
Comment importer l'infrastructure existante dans Terraform ?
Utilisez terraform import pour placer les ressources existantes sous gestion Terraform. Par exemple : terraform import aws_instance.app i-1234567890abcdef0. Après l'importation, écrivez la configuration correspondante. Terraform 1.5+ prend en charge les blocs d'importation dans les fichiers de configuration pour les importations groupées.
Comment gérons-nous les secrets dans Terraform ?
Ne confiez jamais de secrets aux fichiers Terraform. Utilisez terraform.tfvars (exclu de Git), des variables d'environnement (TF_VAR_db_password) ou un gestionnaire de secrets (AWS Secrets Manager, HashiCorp Vault). Marquez les variables sensibles avec sensitive = true pour éviter qu'elles n'apparaissent dans la sortie du plan.
Quel est le coût de la gestion de Terraform ?
Terraform lui-même est gratuit et open source. Terraform Cloud propose un niveau gratuit pour un maximum de 5 utilisateurs avec état à distance et planification/application. Le coût principal est la courbe d'apprentissage (20 à 40 heures pour un ingénieur expérimenté) et la maintenance continue (2 à 4 heures par mois). Ceci est compensé par le temps gagné sur la gestion manuelle de l’infrastructure.
Ce qui vient ensuite
Terraform constitue la base d'une infrastructure automatisée. Combinez-le avec des pipelines CI/CD pour un déploiement automatisé, de la surveillance pour une visibilité opérationnelle et de la reprise après sinistre pour la résilience.
Contactez ECOSIRE pour obtenir des conseils en automatisation de l'infrastructure, ou explorez notre guide DevOps pour les petites entreprises pour obtenir la feuille de route complète.
Publié par ECOSIRE – aider les entreprises à automatiser l'infrastructure cloud.
Rédigé par
ECOSIRE Research and Development Team
Création de produits numériques de niveau entreprise chez ECOSIRE. Partage d'analyses sur les intégrations Odoo, l'automatisation e-commerce et les solutions d'entreprise propulsées par l'IA.
Articles connexes
Automatisation des comptes fournisseurs : réduisez les coûts de traitement de 80 %
Mettez en œuvre l'automatisation des comptes fournisseurs pour réduire les coûts de traitement des factures de 15 $ à 3 $ par facture grâce à l'OCR, à la correspondance à trois voies et aux workflows ERP.
L'IA dans l'automatisation de la comptabilité et de la tenue de livres : le guide de mise en œuvre du CFO
Automatisez la comptabilité avec l'IA pour le traitement des factures, le rapprochement bancaire, la gestion des dépenses et les rapports financiers. Cycles de fermeture 85 % plus rapides.
Agents IA pour l'automatisation des processus métier : des chatbots aux workflows autonomes
Comment les agents IA automatisent les processus métier complexes dans les domaines des ventes, des opérations, des finances et du service client grâce à un raisonnement en plusieurs étapes et à l'intégration de systèmes.