Provisionnement des bases avec Terraform (IaC)
Symptôme
Objectif : définir l'infrastructure des bases (instance, parameter group, réseau) sous forme de code (Infrastructure as Code) avec Terraform ; mettre en place le flux plan/apply, l'état distant et la gestion de la dérive.
1. Choisissez et configurez le provider (aws / google / azurerm)
Définissez le provider du cloud que vous utilisez et figez sa version. Verrouillez le provider hashicorp/aws pour AWS, hashicorp/google pour GCP et hashicorp/azurerm pour Azure dans le bloc required_providers. Figer la version garantit un comportement cohérent dans l'équipe.
PostgreSQL
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "eu-central-1"
}2. Mettez en place l'état distant et le verrouillage
Ne conservez pas le fichier d'état en local ; utilisez un backend distant pour le travail en équipe et la sécurité. Les choix courants sont le backend S3 + une table de verrouillage DynamoDB sur AWS, le backend gcs sur GCP et le backend azurerm (Storage Account) sur Azure. L'état distant empêche les apply concurrents grâce au verrouillage et fait de l'état la source unique de vérité. Comme des mots de passe peuvent figurer en clair dans l'état, gardez le backend chiffré et à accès restreint.
PostgreSQL
terraform {
backend "s3" {
bucket = "company-tfstate"
key = "db/terraform.tfstate"
region = "eu-central-1"
dynamodb_table = "tf-lock"
encrypt = true
}
}3. Définissez la ressource de base de données
Écrivez la ressource principale pour votre moteur et votre cloud : aws_db_instance sur AWS (ou aws_rds_cluster pour Aurora), google_sql_database_instance sur GCP, azurerm_mssql_database sur Azure (pour SQL Server, sous un azurerm_mssql_server). Indiquez-y le moteur, la version, la classe, le stockage et la fenêtre de sauvegarde.
PostgreSQL
resource "aws_db_instance" "pg" {
identifier = "app-db"
engine = "postgres"
engine_version = "16"
instance_class = "db.t3.medium"
allocated_storage = 50
db_name = "appdb"
username = "pgadmin"
password = var.db_password
backup_retention_period = 7
}SQL Server
resource "azurerm_mssql_database" "db" {
name = "appdb"
server_id = azurerm_mssql_server.srv.id
sku_name = "S1"
}4. Écrivez le parameter group sous forme de code
Définissez les paramètres de la base (max_connections, work_mem, jeu de caractères) avec une ressource de paramètres, et non manuellement dans la console. Utilisez aws_db_parameter_group sur AWS, settings.database_flags dans google_sql_database_instance sur GCP, et la ressource de configuration serveur sur Azure. Les paramètres sont alors versionnés et reproductibles.
PostgreSQL
resource "aws_db_parameter_group" "pg" {
name = "app-pg16"
family = "postgres16"
parameter {
name = "max_connections"
value = "200"
}
}
# inside aws_db_instance:
# parameter_group_name = aws_db_parameter_group.pg.name5. Transmettez les secrets via des variables et un gestionnaire de secrets
N'écrivez pas le mot de passe en dur dans un fichier .tf ; définissez-le comme variable sensible (variable ... sensitive = true) et fournissez la valeur via une variable d'environnement TF_VAR_, un gestionnaire de secrets (AWS Secrets Manager, Vault) ou un secret CI. Attention : la valeur est écrite dans le fichier d'état, l'état distant doit donc être chiffré. L'approche la plus propre consiste à ne jamais transmettre le mot de passe à Terraform et à le lire depuis une ressource du gestionnaire de secrets.
PostgreSQL
variable "db_password" {
type = string
sensitive = true
}
# CI/shell:
export TF_VAR_db_password="$(vault kv get -field=pw secret/db)"6. Exécutez le flux plan et apply
Préparez d'abord le provider/le backend avec terraform init, voyez ce qui va changer avec terraform plan, approuvez, puis appliquez avec terraform apply. N'appliquez pas sans avoir examiné la sortie du plan ; en CI, le flux sûr consiste à publier le 'plan' en commentaire de PR et à appliquer après approbation humaine. Repérez les changements destructeurs (par ex. recréation d'instance) grâce au marqueur -/+ dans la sortie du plan.
PostgreSQL
terraform init
terraform plan -out=plan.tfplan
terraform apply plan.tfplan7. Détectez et corrigez la dérive
Si quelqu'un fait une modification manuelle dans la console, l'infrastructure réelle et l'état divergent (drift). Les différences qui apparaissent dans terraform plan « alors que rien n'aurait dû changer » révèlent la dérive ; la différence se lit avec terraform refresh/plan. Soit vous reportez la modification dans le code, soit vous ramenez l'infrastructure au code avec apply. Interdisez par principe les modifications manuelles ; le code doit être la source unique de vérité.
PostgreSQL
# drift check (when no changes are expected):
terraform plan
# expect 'No changes'; any diff means drift
# bring an existing resource into state with import:
terraform import aws_db_instance.pg app-db