Même l’architecture d’infrastructure la plus sophistiquée ne peut pas prévenir toutes les erreurs. C’est pourquoi il est essentiel de surveiller de manière proactive les opérations Terraform - en particulier celles qui peuvent avoir des conséquences potentiellement destructrices. L’objectif est de détecter précocement les modifications critiques et de déclencher automatiquement des alertes, avant qu’un rayon d’impact incontrôlé ne survienne.
Oui, bien sûr - votre ingénieur système vous rappellera sans doute que Terraform affiche l’intégralité du plan avant l’exécution d’un apply et qu’il faut encore confirmer manuellement l’exécution par la saisie de "yes".
Ce que votre ingénieur ne vous dit pas : il ne lit en réalité pas le plan avant de le lancer.
« Ça ira. »
Système d’alerte précoce : Analyse automatisée du plan
Terraform propose, avec l’option -json, une possibilité d’évaluer automatiquement les informations du plan. Cela permet d’identifier les suppressions prévues (destroy) et de déclencher automatiquement les actions appropriées, comme une alerte via Slack ou une interruption automatique du pipeline CI/CD.
Un autre indicateur précoce est la valeur de retour de terraform plan -detailed-exitcode : un code de sortie 2 signale des modifications prévues, y compris des suppressions.
Exemple : Script Bash pour l’analyse du plan
Ce script peut être intégré comme hook dans le pipeline CI/CD. Si des suppressions sont détectées, une notification est immédiatement envoyée – ou, en option, le déploiement est automatiquement interrompu.
Un exemple de script à titre d’orientation :
#!/bin/bash # Automated Plan Analysis Script set -e # Exit on any error # Create the Terraform plan and export it in JSON format terraform plan -out=tfplan -detailed-exitcode PLAN_EXIT_CODE=$? # Check if there are changes (exit code 2) if [ $PLAN_EXIT_CODE -eq 2 ]; then terraform show -json tfplan > plan.json # Analyze planned deletions with more robust jq query DELETIONS=$(jq -r '.resource_changes[]? | select(.change.actions[]? == "delete") | .address' plan.json 2>/dev/null) if [ -n "$DELETIONS" ]; then echo "BLAST RADIUS ALERT: Planned deletions detected:" echo "$DELETIONS" | while read -r resource; do echo " - $resource" done # Send alert with proper error handling if ! curl -f -X POST "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK" \ -H 'Content-type: application/json' \ --data "{\"text\":\"ALERT: Terraform Destroy detected in $WORKSPACE:\\n$DELETIONS\"}"; then echo "Warning: Failed to send Slack notification" fi exit 2 fi fi
Surveillance des journaux basée sur le Cloud avec alerte
Pour les environnements de production, une solution de monitoring centralisée et native au Cloud est recommandée. Cela peut par exemple être réalisé via un Splunk exécuté localement dans votre centre de données, ou via des services Cloud comme AWS CloudWatch ou Oracle Logging. L’objectif est d’identifier les entrées de journal suspectes contenant des mots-clés destructeurs comme « destroy » et de déclencher des alertes en temps réel.
Remarque : Les exemples suivants sont fournis à titre indicatif. Bien qu’ils contiennent les déclarations de ressources nécessaires, ils ne sont pas encore opérationnels de bout en bout. Les éléments manquants tels que versions.tf et variables.tf sont laissés à l’appréciation du lecteur suffisamment expérimenté.
Exemple : Intégration AWS CloudWatch
Les alertes peuvent être directement reliées à un aws_sns_topic, qui transmet ensuite les notifications par e-mail, Slack, PagerDuty ou d’autres systèmes d’alerte. Ainsi, aucun terraform destroy critique ne passe inaperçu.
provider "aws" { region = "eu-central-1" } resource "aws_cloudwatch_log_group" "terraform_logs" { name = "/terraform/cicd" retention_in_days = 7 tags = { Environment = "production" Purpose = "terraform-monitoring" } } resource "aws_cloudwatch_metric_filter" "terraform_destroy_filter" { name = "terraform-destroy-keyword" log_group_name = aws_cloudwatch_log_group.terraform_logs.name pattern = "\"destroy\"" metric_transformation { name = "DestroyMatches" namespace = "Terraform/CI" value = "1" unit = "Count" } } resource "aws_sns_topic" "alerts" { name = "terraform-blast-radius-alerts" tags = { Environment = "production" Purpose = "terraform-alerts" } } resource "aws_sns_topic_subscription" "email_alert" { topic_arn = aws_sns_topic.alerts.arn protocol = "email" endpoint = var.alert_email } resource "aws_cloudwatch_metric_alarm" "blast_radius_alarm" { alarm_name = "Terraform-Destroy-Detected" alarm_description = "Detects destroy operations in Terraform CI output" comparison_operator = "GreaterThanThreshold" evaluation_periods = 1 threshold = 0 metric_name = "DestroyMatches" namespace = "Terraform/CI" statistic = "Sum" period = 60 treat_missing_data = "notBreaching" insufficient_data_actions = [] alarm_actions = [aws_sns_topic.alerts.arn] ok_actions = [aws_sns_topic.alerts.arn] tags = { Environment = "production" Purpose = "blast-radius-monitoring" } }
Exemple : OCI Logging avec alerte
Dans Oracle Cloud Infrastructure, vous utilisez le service Logging en combinaison avec une requête de journalisation, une alarme et le service de notifications. Cela permet d’identifier les actions destructrices comme terraform destroy à l’aide de mots-clés dans le flux de logs de la pipeline CI/CD ou dans les Audit Logs.
Étapes de configuration :
- Configurer un groupe de logs (Log Group) pour vos logs de build ou vos Audit Logs
- Créer une Logging Search avec une requête du type data.message CONTAINS "destroy"
- Définir une alarme qui se déclenche en cas de correspondance
- Connecter un Notification Topic (e-mail, PagerDuty, etc.)
Exemple d’alarme via Terraform :
resource "oci_logging_log_group" "terraform_logs" { display_name = "terraform-ci-logs" compartment_id = var.compartment_id freeform_tags = { "Environment" = "production" "Purpose" = "terraform-monitoring" } } resource "oci_logging_log" "cicd_log" { display_name = "terraform-cicd-log" log_group_id = oci_logging_log_group.terraform_logs.id log_type = "CUSTOM" configuration { source { category = "write" resource = var.compartment_id service = "objectstorage" source_type = "OCISERVICE" } compartment_id = var.compartment_id } is_enabled = true retention_duration = 30 } resource "oci_ons_notification_topic" "alerts" { name = "terraform-destroy-alerts" compartment_id = var.compartment_id description = "Alerts for blast-radius related events" freeform_tags = { "Environment" = "production" "Purpose" = "terraform-alerts" } } resource "oci_ons_subscription" "email_subscription" { compartment_id = var.compartment_id topic_id = oci_ons_notification_topic.alerts.id protocol = "EMAIL" endpoint = var.alert_email } resource "oci_monitoring_alarm" "terraform_destroy_alarm" { display_name = "Terraform-Destroy-Detected" compartment_id = var.compartment_id metric_compartment_id = var.compartment_id query = <<-EOQ LoggingAnalytics[1m]{ logGroup = "${oci_logging_log_group.terraform_logs.display_name}", log = "${oci_logging_log.cicd_log.display_name}" } | where data.message =~ ".*destroy.*" | count() EOQ severity = "CRITICAL" body = "Terraform destroy operation detected in CI/CD pipeline!" is_enabled = true pending_duration = "PT1M" repeat_notification_duration = "PT15M" resolution = "1m" suppression { description = "Planned maintenance window" # time_suppress_from und time_suppress_until can be added if needed } destinations = [oci_ons_notification_topic.alerts.id] freeform_tags = { "Environment" = "production" "Purpose" = "blast-radius-monitoring" } }
Remarque : La requête de journalisation utilise une recherche textuelle simple. Pour les environnements de production, il est conseillé d’utiliser des filtres plus précis – par exemple des expressions régulières ou des champs de logs structurés, si vos outils CI fournissent de tels formats.
Alternativement, vous pouvez utiliser le moteur de requêtes LoggingSearch, plus simple, si Logging Analytics n’est pas activé dans votre tenancy.
Valeur ajoutée : Cette méthode peut également être étendue dans OCI aux actions apply, aux violations de policies ou aux drifts, à condition que les logs soient correctement alimentés (par exemple via les sorties de Terraform Plan, les alertes Sentinel ou les événements d’audit).
✅Checklist : Préparation au Blast Radius
Cette checklist peut vous aider à rendre votre infrastructure aussi résiliente que possible.
✅ Mesures préventives
- [ ] États segmentés selon l’impact du Blast Radius
- [ ] Règles de cycle de vie mises en œuvre pour les ressources critiques
- [ ] Validations d’état distants configurées
- [ ] Policy-as-Code pour les opérations de destruction
- [ ] Analyse automatisée du plan activée
- [ ] Cartographie des dépendances inter-états réalisée
🚨 Préparations en cas d’incident
- [ ] Stratégie de sauvegarde des états mise en place
- [ ] Scripts d’importation pour les ressources critiques testés
- [ ] Playbooks d’intervention en cas d’incident disponibles
- [ ] Formation des équipes à la chirurgie de state réalisée
- [ ] Monitoring et alerting pour les événements Blast Radius actifs
✍️Planification rigoureuse et état d’esprit
Une mise en œuvre réussie de Terraform à l’échelle entreprise exige également :
- Architecture proactive : concevoir les états en fonction de l’impact du Blast Radius
- Programmation défensive : implémenter des garde-fous et des validations
- Monitoring et alerting : détecter les événements Blast Radius en amont
- Préparation à la reprise : être prêt pour le pire des scénarios
Conclusion : Des explosions contrôlées plutôt que le chaos
Important : Le Blast Radius Management n’est pas une configuration ponctuelle, mais un processus continu.
Tout l’art consiste à trouver le juste équilibre entre flexibilité et contrôle – exactement comme dans le principe de Goldilocks que nous avons déjà décrit en détail dans un précédent article.
Car la meilleure des explosions est celle qui ne se produit pas.