Confidentialite¶
Classification des données OpenTofu¶
Les workflows OpenTofu manipulent des données sensibles qui révèlent la topologie, les identifiants et la configuration de l'infrastructure. La classification est Restreint pour les éléments les plus critiques.
Pour le cadre complet de classification, consultez la rubrique Classification et zones de confiance.
| Donnée | Classification | Risque si expose |
|---|---|---|
| State file | Restreint | Contient identifiants, cles API, topologie complète de l'infra |
| Variables sensibles (tfvars) | Restreint | Mots de passe, tokens, cles d'API en clair |
Plan output (tfplan) | Confidentiel | Révèle les changements prevus et la structure de l'infrastructure |
Code HCL (.tf) | Confidentiel | Révèle l'architecture, les choix techniques, les patterns déployés |
| Logs d'execution | Confidentiel | Peuvent contenir des valeurs sensibles en cas de misconfiguration |
| Provider credentials | Restreint | Accès complet aux APIs cloud (GCP, AWS, Azure) |
Le state est le secret le plus critique
Le fichier terraform.tfstate contient en clair les identifiants, cles API, mots de passe de base de données, et la topologie complète de l'infrastructure. Sa compromission equivaut a la compromission de toute l'infrastructure.
Sécurité du state file¶
Backend remote chiffre¶
Ne jamais stocker le state en local. Utiliser un backend remote avec chiffrement au repos :
terraform {
backend "gcs" {
bucket = "myorg-tofu-state"
prefix = "prod/network"
# Chiffrement au repos par defaut (Google-managed ou CMEK)
}
}
terraform {
backend "s3" {
bucket = "myorg-tofu-state"
key = "prod/network/terraform.tfstate"
region = "eu-west-3"
encrypt = true # Chiffrement SSE-S3
kms_key_id = "arn:aws:kms:..." # Ou SSE-KMS pour cle dediee
dynamodb_table = "tofu-state-lock" # Locking
}
}
Contrôle d'accès au bucket de state¶
# GCS — IAM restreint au state bucket
resource "google_storage_bucket_iam_binding" "state_access" {
bucket = "myorg-tofu-state"
role = "roles/storage.objectAdmin"
members = [
"serviceAccount:tofu-ci@myorg.iam.gserviceaccount.com",
]
}
Pas de state local
Ajoutez *.tfstate et *.tfstate.backup au .gitignore global. Un state commit par erreur dans Git expose toute l'infrastructure.
Versioning du state¶
Activez le versioning sur le bucket de state pour permettre la recovery en cas de corruption. Sur GCS : gcloud storage buckets update gs://myorg-tofu-state --versioning. Sur S3 : activez le versioning via put-bucket-versioning.
Secrets dans le state¶
Marquage des outputs sensibles¶
Les outputs contenant des secrets doivent etre marques sensitive pour eviter leur affichage dans les logs :
output "database_password" {
value = google_sql_user.app.password
sensitive = true
}
output "api_key" {
value = random_password.api_key.result
sensitive = true
}
Limite du marquage sensitive
Le flag sensitive = true masque la valeur dans tofu output et les logs, mais elle reste en clair dans le state file. Le chiffrement du backend est la seule protection reelle.
Vault provider pour les secrets dynamiques¶
Plutôt que de stocker des secrets statiques, utilisez HashiCorp Vault pour générer des credentials ephemeres :
# Recuperer un secret dynamique depuis Vault
data "vault_generic_secret" "db_creds" {
path = "database/creds/app-role"
}
resource "google_sql_user" "app" {
name = data.vault_generic_secret.db_creds.data["username"]
password = data.vault_generic_secret.db_creds.data["password"]
instance = google_sql_database_instance.main.name
}
Les secrets dynamiques expirent automatiquement, limitant la fenêtre d'exposition en cas de compromission du state.
Sécurité du plan output¶
Le fichier tfplan génère par tofu plan -out=tfplan contient les changements prevus et peut révéler des informations sur l'infrastructure existante.
Ajoutez *.tfplan au .gitignore. En CI/CD, stockez le plan comme artefact ephemere avec une retention courte (1-4 heures) :
# GitHub Actions — artefact ephemere
- uses: actions/upload-artifact@v4
with:
name: tfplan
path: infra/tfplan
retention-days: 1
RBAC — Separation plan / apply¶
Tous les membres de l'équipe ne doivent pas avoir les mêmes droits. La separation entre plan et apply est une mesure de sécurité fondamentale.
| Rôle | plan | apply | state read | state write | Qui |
|---|---|---|---|---|---|
| Développeur | Oui | Non | Non | Non | Équipe dev |
| Ops | Oui | Non | Oui | Non | Équipe infrastructure |
| Lead Ops | Oui | Oui | Oui | Oui | Responsables infra |
| CI/CD (prod) | Oui | Oui | Oui | Oui | Service account pipeline |
| CI/CD (dev) | Oui | Oui | Oui | Oui | Service account pipeline dev |
Principe du moindre privilege
En production, seul le pipeline CI/CD et les leads ops peuvent exécuter tofu apply. Un développeur peut lancer tofu plan pour previsualiser ses changements, mais l'application passe par une PR approuvee et le pipeline.
Audit trail¶
Chaque tofu apply modifie le state. Activez le versioning sur le bucket (voir section précédente) pour conserver un historique complet des versions.
Les logs du pipeline CI/CD constituent l'audit trail principal :
- Qui a declenche le pipeline (auteur du commit / approbateur de la PR)
- Quoi a change (diff du code HCL dans la PR)
- Quand le
tofu applya ete execute (timestamp du job) - Résultat (succès/echec, ressources créées/modifiées/detruites)
Scrub des logs
Configurez le pipeline pour masquer les variables sensibles dans les logs. OpenTofu masque les outputs sensitive, mais les providers peuvent afficher des valeurs dans les messages d'erreur.
Isolation réseau¶
Accès restreint au state backend¶
Le bucket de state ne doit etre accessible que depuis :
- Le réseau du pipeline CI/CD
- Les postes des ops autorises (VPN)
- Jamais depuis l'internet public
# S3 — Bucket policy restreignant l'acces par VPC endpoint
resource "aws_s3_bucket_policy" "state" {
bucket = aws_s3_bucket.state.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Sid = "RestrictToVPCEndpoint"
Effect = "Deny"
Principal = "*"
Action = "s3:*"
Resource = ["${aws_s3_bucket.state.arn}/*"]
Condition = {
StringNotEquals = {
"aws:sourceVpce" = var.vpc_endpoint_id
}
}
}]
})
}
Sur GCS, utilisez les VPC Service Controls pour créer un perimetre autour du bucket de state.
Defense en profondeur
Combinez le chiffrement du backend, le contrôle d'accès IAM, l'isolation réseau et l'audit trail. Aucune mesure isolee n'est suffisante pour protéger le state file.