Sägetstrasse 18, 3123 Belp, Switzerland +41 79 173 36 84 info@ict.technology

      Terraform @ Scale - Partie 3c : Monitoring et alerting pour les événements Blast Radius

      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 :

      1. Configurer un groupe de logs (Log Group) pour vos logs de build ou vos Audit Logs
      2. Créer une Logging Search avec une requête du type data.message CONTAINS "destroy"
      3. Définir une alarme qui se déclenche en cas de correspondance
      4. 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.