Passer au contenu principal

Production (Terraform)

Gestion des secrets

Les secrets dans Terraform sont une problématique délicate : HCL est un fichier texte versionné dans Git, et les state files stockent les valeurs en clair. Plusieurs niveaux de protection sont nécessaires pour éviter les fuites.

Variables d'environnement

La méthode la plus simple pour les credentials de providers. Terraform lit automatiquement les variables d'environnement préfixées par TF_VAR_ :

# Pour une variable Terraform "db_password"
export TF_VAR_db_password="MonMotDePasse"
terraform apply

# Pour les credentials AWS
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
terraform plan

En CI/CD, ces variables sont injectées comme secrets de pipeline, jamais écrits dans les fichiers.

tfvars hors Git

# .gitignore
*.tfvars
!example.tfvars
# terraform.tfvars — local uniquement, jamais commité
db_password = "MonMotDePasse"
api_key     = "sk-..."

Provider HashiCorp Vault

Pour les équipes utilisant HashiCorp Vault comme gestionnaire de secrets :

provider "vault" {
  address = "https://vault.example.com"
  # Authentification via token ou rôle AWS/Kubernetes
}

data "vault_kv_secret_v2" "db" {
  mount = "secret"
  name  = "prod/database"
}

resource "aws_db_instance" "main" {
  username = data.vault_kv_secret_v2.db.data["username"]
  password = data.vault_kv_secret_v2.db.data["password"]
}

AWS Secrets Manager

data "aws_secretsmanager_secret_version" "db" {
  secret_id = "prod/myapp/database"
}

locals {
  db_creds = jsondecode(data.aws_secretsmanager_secret_version.db.secret_string)
}

resource "aws_db_instance" "main" {
  username = local.db_creds["username"]
  password = local.db_creds["password"]
  # ...
  lifecycle {
    ignore_changes = [password]   # si le mot de passe est géré par Secrets Manager
  }
}

Protéger le state

Le state contient les secrets en clair. Protection minimale :

# Backend S3 avec chiffrement
terraform {
  backend "s3" {
    bucket  = "mon-bucket-tfstate"
    key     = "prod/terraform.tfstate"
    region  = "eu-west-1"
    encrypt = true                      # SSE-S3 ou SSE-KMS
    kms_key_id = "arn:aws:kms:..."     # SSE-KMS recommandé
  }
}
  • Bucket S3 : accès privé, versioning activé, MFA delete
  • Politique IAM : accès au state limité aux rôles Terraform uniquement
  • Logs d'accès activés sur le bucket

Variables sensibles dans le plan

variable "db_password" {
  type      = string
  sensitive = true    # masqué dans terraform plan et apply
}

output "db_connection_string" {
  value     = "postgres://user:${var.db_password}@${aws_db_instance.main.endpoint}/db"
  sensitive = true    # masqué dans terraform output
}