Terraform Sentinel permet de définir des règles de conformité qui s’appliquent à toutes les exécutions Terraform — avant d’appliquer. Un plan qui crée une instance sans tag, expose un bucket S3 publiquement ou utilise un type d’instance non approuvé est bloqué automatiquement.
Sentinel dans le workflow Terraform Cloud
Plan → Sentinel (Policy Check) → Apply (si policies passent)
↓
Policy violated → Apply bloqué
Trois niveaux de sévérité :
- Advisory — avertissement, le plan continue
- Soft Mandatory — bloquant, mais les administrateurs peuvent passer outre
- Hard Mandatory — bloquant, personne ne peut passer outre
Écrire une politique Sentinel
# policy/require-tags.sentinel
# Toutes les ressources AWS doivent avoir les tags Environment, Team et CostCenter
import "tfplan/v2" as tfplan
# Récupérer toutes les ressources AWS dans le plan
all_aws_resources = filter tfplan.resource_changes as _, rc {
rc.provider_name is "registry.terraform.io/hashicorp/aws" and
rc.change.actions contains "create"
}
# Vérifier que les tags requis sont présents
required_tags = ["Environment", "Team", "CostCenter"]
tags_are_valid = rule {
all all_aws_resources as _, resource {
all required_tags as tag {
tag in keys(resource.change.after.tags)
}
}
}
# Le résultat de la policy
main = rule {
tags_are_valid
}
Politique de types d’instances autorisés
# policy/allowed-instance-types.sentinel
import "tfplan/v2" as tfplan
# Liste blanche des types d'instances autorisés
allowed_types = [
"t3.micro", "t3.small", "t3.medium",
"m6i.large", "m6i.xlarge",
"c6i.large"
]
ec2_instances = filter tfplan.resource_changes as _, rc {
rc.type is "aws_instance" and
rc.change.actions contains "create"
}
instance_types_valid = rule {
all ec2_instances as _, instance {
instance.change.after.instance_type in allowed_types
}
}
main = rule with soft-fail { # soft-fail : bloquant mais contournable par un admin
instance_types_valid
}
Politique de sécurité S3
# policy/no-public-s3.sentinel
import "tfplan/v2" as tfplan
s3_buckets = filter tfplan.resource_changes as _, rc {
rc.type is "aws_s3_bucket_public_access_block" and
rc.change.actions contains "create"
}
s3_not_public = rule {
all s3_buckets as _, bucket {
bucket.change.after.block_public_acls is true and
bucket.change.after.block_public_policy is true and
bucket.change.after.ignore_public_acls is true and
bucket.change.after.restrict_public_buckets is true
}
}
main = rule {
s3_not_public
}
Configurer les policies dans Terraform Cloud
# sentinel.hcl — dans le repository de policies
policy "require-tags" {
source = "./require-tags.sentinel"
enforcement_level = "hard-mandatory"
}
policy "allowed-instance-types" {
source = "./allowed-instance-types.sentinel"
enforcement_level = "soft-mandatory"
}
policy "no-public-s3" {
source = "./no-public-s3.sentinel"
enforcement_level = "hard-mandatory"
}
Tester les policies localement
# Installer le Sentinel CLI
brew install hashicorp/tap/sentinel
# Générer un mock plan
terraform plan -out=plan.tfplan
terraform show -json plan.tfplan > tfplan.json
# Tester la policy
sentinel test -run=require-tags
# Mode verbose pour le debug
sentinel apply -trace require-tags.sentinel
Notre formation Terraform couvre la gouvernance et Terraform Cloud dans le cadre de pratiques IaC avancées.