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

    Terraform @ Scale - Teil 3c: Monitoring und Alerting für Blast-Radius Events

    Selbst die ausgeklügeltste Infrastrukturarchitektur kann nicht jeden Fehler verhindern. Deshalb ist es entscheidend, Terraform-Operationen proaktiv zu überwachen - insbesondere jene, die potenziell destruktive Auswirkungen haben. Ziel ist, kritische Änderungen frühzeitig zu erkennen und automatisiert zu alarmieren, bevor es zu einem unkontrollierten Blast-Radius kommt.

    Ja klar – Ihr System Engineer weist Sie mit Sicherheit jetzt darauf hin, dass Terraform vor der Ausführung eines apply den kompletten Plan anzeigt und man die Ausführung vorher noch durch Eingabe von "yes" freigeben muss.

    Was Ihr Engineer allerdings nicht sagt: Er liest den Plan nicht tatsächlich, bevor er ihn ausführen lässt.

    „Wird schon gutgehen.“

    Frühwarnsystem: Automatisierte Plan-Analyse

    Terraform bietet mit dem -json-Flag eine Möglichkeit, Plan-Informationen maschinell auszuwerten. Dies erlaubt es, geplante Löschungen (destroy) zu erkennen und automatisiert entsprechende Maßnahmen einzuleiten, z. B. eine Slack-Warnung oder ein automatisches Abbrechen der CI/CD-Pipeline.

    Ein alternativer Frühindikator ist der Rückgabewert von terraform plan -detailed-exitcode: Ein Exit-Code 2 signalisiert geplante Änderungen, inklusive geplanter Löschungen.

    Beispiel: Bash-Skript zur Plan-Auswertung

    Dieses Skript kann als Hook in der CI/CD-Pipeline integriert werden. Werden geplante Löschungen erkannt, erfolgt sofortige Benachrichtigung – oder optional ein automatischer Stopp des Rollouts.

    Ein Beispiel-Skript zur Orientierung:


    #!/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
    

    Cloud-basiertes Log-Monitoring mit Alarmierung

    Für produktive Umgebungen empfiehlt sich ein zentrales, Cloud-natives Monitoring. Das kann zum Beispiel über ein Splunk realisiert werden, das lokal in Ihrem Rechenzentrum läuft. Oder Cloud-Services wie AWS CloudWatch oder Oracle Logging. Ziel ist es, verdächtige Logeinträge mit destruktiven Schlüsselwörtern wie „destroy“ zu erfassen und in Echtzeit Alarme auszulösen.

    Hinweis: Die folgenden Beispiele dienen zur Orientierung und bieten in dieser Form zwar die nötigen Ressourcendeklarationen, sind aber noch nicht End-to-End lauffähig. Die noch fehlenden Details wie versions.tf und variables.tf überlasse ich dem ausreichend fachkundigen Leser.

    Beispiel: AWS CloudWatch Integration

    Die Alarme können direkt an ein aws_sns_topic angebunden werden, das wiederum E-Mail, Slack, PagerDuty oder andere Notifikationssysteme bedient. So ist gewährleistet, dass kein kritisches terraform destroy unbemerkt bleibt.


    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"
      }
    }

    Beispiel: OCI Logging mit Alarmierung

    In Oracle Cloud Infrastructure verwenden Sie den Logging-Service in Kombination mit einer Logging Query, einem Alarm und dem Notifications-Service. So erkennen Sie destruktive Aktionen wie terraform destroy anhand von Schlüsselwörtern im Logstream der CI/CD-Pipeline oder der Audit Logs.

    Schritte zur Konfiguration:

    1. Log Group für Ihre Build Logs oder Audit Logs einrichten
    2. Logging Search mit Query wie data.message CONTAINS "destroy"
    3. Alarm definieren, der bei Treffern auslöst
    4. Notification Topic anbinden (E-Mail, PagerDuty, etc.)

    Beispiel-Alarm über 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"
      }
    }
    

    Hinweis: Die Logging Query verwendet eine einfache Textsuche. Für produktive Umgebungen sollten Sie ggf. präzisere Filter verwenden – z. B. reguläre Ausdrücke oder strukturierte Logfelder, sofern Ihre CI-Tools strukturierte Logs liefern. 
    Alternativ kann auch die einfachere LoggingSearch-Query-Engine verwendet werden, falls Logging Analytics in Ihrer Tenancy nicht aktiviert ist.

    Zusatznutzen: Diese Methode lässt sich in OCI ebenfalls auf apply-Aktionen, Policy-Verletzungen oder Drifts ausweiten, sofern die Logs sauber beschickt werden (z. B. durch Terraform Plan-Ausgaben, Sentinel-Warnungen oder Audit-Events).

    ✅Checkliste: Blast Radius Readiness

    Diese Checkliste kann Ihnen dabei helfen, Ihre Infrastruktur so widerstandsfähig wie möglich zu bauen.

    ✅ Präventive Maßnahmen

    • [ ] States nach Blast Radius Impact segmentiert
    • [ ] Lifecycle Rules für kritische Ressourcen implementiert
    • [ ] Remote State Validations vorhanden
    • [ ] Policy-as-Code für Destroy Operations
    • [ ] Automated Plan Analysis aktiviert
    • [ ] Cross-State Dependency Mapping erstellt

    🚨 Vorbereitungen für den Ernstfall

    • [ ] State Backup Strategy implementiert
    • [ ] Import Scripts für kritische Ressourcen getestet
    • [ ] Incident Response Playbooks vorhanden
    • [ ] Team Training für State Surgery durchgeführt
    • [ ] Monitoring und Alerting für Blast Radius Events aktiv

    ✍️Sorgfältige Planung und Mindsets

    Erfolgreiche Terraform-Implementierungen auf Enterprise-Niveau erfordern außerdem:

    • Proaktive Architektur: States nach Blast Radius Impact designen
    • Defensive Programmierung: Guardrails und Validations implementieren
    • Monitoring und Alerting: Blast Radius Events frühzeitig erkennen
    • Recovery Preparedness: Für den Ernstfall gerüstet sein

    Fazit: Kontrollierte Explosionen statt Chaos

    Wichtig: Blast Radius Management ist kein einmaliges Setup, sondern ein kontinuierlicher Prozess.

    Die Kunst liegt darin, die Balance zwischen Flexibilität und Kontrolle zu finden – genau wie beim Goldilocks-Prinzip, das wir in einem vorherigen Artikel bereits ausführlich geschildert haben.

    Denn die beste Explosion ist die, die gar nicht erst passiert.