Policy as Code
La Policy as Code applique à l'infrastructure les mêmes principes que le code applicatif : les règles de sécurité et de conformité sont définies dans des fichiers versionnables, testables et automatiquement vérifiables. Elle remplace les audits manuels périodiques par des contrôles systématiques à chaque déploiement.
tfsec : scanning de sécurité
# Installation
curl -s https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash
# Scanner le répertoire courant
tfsec .
# Avec format enrichi
tfsec . --format lovely
# Ignorer une règle spécifique
tfsec . --exclude aws-s3-enable-bucket-logging# Ignorer une règle sur une ressource spécifique
resource "aws_s3_bucket" "logs" {
bucket = "mon-bucket-logs"
#tfsec:ignore:aws-s3-enable-bucket-logging
}Checkov : compliance scanning
pip install checkov
# Scanner
checkov -d . --framework terraform
# Avec rapport détaillé
checkov -d . --output-file-path reports/ --output json
# Seuil d'échec
checkov -d . --hard-fail-on CRITICALCheckov couvre 1000+ règles : CIS Benchmarks, NIST, PCI-DSS, SOC2. Il supporte Terraform, CloudFormation, Kubernetes, Dockerfile et plus.
OPA (Open Policy Agent) avec Conftest
OPA permet d'écrire des politiques personnalisées en langage Rego :
brew install conftest # ou télécharger le binaire# policy/terraform.rego
package main
deny[msg] {
resource := input.resource.aws_security_group[_]
ingress := resource.ingress[_]
ingress.cidr_blocks[_] == "0.0.0.0/0"
ingress.from_port <= 22
ingress.to_port >= 22
msg := sprintf("Security group '%v' permet SSH depuis 0.0.0.0/0", [resource])
}
deny[msg] {
resource := input.resource.aws_s3_bucket[name]
not resource.server_side_encryption_configuration
msg := sprintf("Bucket S3 '%v' n'est pas chiffré", [name])
}# Vérifier le plan Terraform contre les politiques
terraform show -json tfplan | conftest test -p policy/ -
# Tester les fichiers HCL directement
conftest test -p policy/ main.tfSentinel (Terraform Cloud/Enterprise)
Sentinel est le framework policy-as-code de HashiCorp, intégré nativement dans Terraform Cloud et Terraform Enterprise. Les politiques sont évaluées entre le plan et l'apply et peuvent bloquer le déploiement.
# policy/restrict_instance_types.sentinel
import "tfplan/v2" as tfplan
allowed_types = ["t3.micro", "t3.small", "t3.medium"]
main = rule {
all tfplan.resource_changes as _, rc {
rc.type is not "aws_instance" or
rc.change.after.instance_type in allowed_types
}
}Intégration CI
# .gitlab-ci.yml
security_scan:
stage: validate
script:
- terraform fmt -check -recursive
- terraform validate
- tfsec . --format lovely --exit-code 1
- checkov -d . --hard-fail-on CRITICAL
- terraform plan -out=tfplan
- terraform show -json tfplan | conftest test -p policy/ -
only: [merge_requests, main]