Webhook icon
WorkingDirectory icon
TerraformCLI icon
Docker icon
Script icon
Process icon
If icon
SlackIncomingWebhook icon
Fail icon
Log icon

Automated Terraform Plan Blast-Radius & Stateful Destruction Gate

Automatically analyze Terraform execution plans for stateful destruction and blast radius, alert Slack, and gate deployments with Kestra.

Categories
CoreInfrastructure

Accidental destruction of stateful infrastructure (such as production databases, persistent volumes, or object storage) is one of the most catastrophic incidents that can occur in cloud operations. While CI/CD pipelines commonly automate terraform plan, raw plan text often spans thousands of lines, burying destructive actions (["delete"] or ["delete", "create"]) beneath harmless property additions or tag changes.

Unlike manual approval pauses that halt workflows for human review or Infracost gates that only calculate dollar expenditure, this blueprint automatically evaluates the actual Terraform execution plan (terraform show -json). It deterministically inspects planned resource operations, flags stateful infrastructure destruction, computes a grounded blast-radius score (0-100), delivers actionable Slack notifications, generates auditable Markdown and JSON report artifacts, and enforces an automated deployment gate before changes reach production.

Architecture

Webhook Trigger / Direct Run
       ↓
WorkingDirectory (Terraform Workspace)
       ↓
TerraformCLI (Evaluate Uploaded Plan OR init & plan & show -json)
       ↓
Python Risk Analyzer (Blast-Radius Scoring & Stateful Classification)
       ↓
If [Elevated Risk & notify_slack]: Slack Webhook Notification
       ↓
If [REJECTED / APPROVAL_REQUIRED]
    ├── If [fail_on_rejection: true]: Fail Task (Halt Deployment)
    └── If [fail_on_rejection: false]: Log Warning (Advisory Mode)
       ↓
Outputs & Artifacts (Score, Verdict, JSON Report, Markdown Scorecard)

Grounded Facts vs. Heuristic Risk Assessment

The risk analyzer separates verifiable plan measurements from heuristic scoring:

  • Measured Grounded Facts: Exact counts extracted directly from HashiCorp Terraform 1.0+ JSON specification (resource_changes array). Quantifies created, updated, deleted, and replaced resources, as well as exact keyword and provider matches for stateful and major infrastructure resources.
  • Heuristic Blast-Radius Score (0-100): A transparent mathematical calculation reflecting total physical operational footprint across the target cloud estate. Stateful destructions (+50 pts) and replacements (+45 pts) carry heavy impact, followed by major infrastructure touches (+35/+30 pts), standard deletions (+15 pts), in-place updates (+3 pts), and additions (+1 pt).
  • Policy Gate Verdict:
    • REJECTED: Stateful destruction, deletions exceeding max_allowed_deletions, or blast radius score $\ge$ blast_radius_rejection_threshold.
    • APPROVAL_REQUIRED: Elevated blast radius score exceeding blast_radius_warning_threshold when require_approval_on_warning is enabled.
    • WARNING: Score exceeds warning threshold but remains within advisory limits.
    • APPROVED: Clean additive changes or no-op plans within safe boundaries.

Deployment Gate & Advisory Modes

The flow supports two operational modes controlled by fail_on_rejection:

  • Advisory & Audit Mode (fail_on_rejection: false, default): When policy violations or high blast radius are detected, the flow logs a high-severity warning and dispatches Slack notifications without halting execution. This safe default allows non-blocking ad-hoc evaluation, demos, and visibility without prematurely failing unconfigured pipelines.
  • Enforcing Policy Gate Mode (fail_on_rejection: true): Any plan evaluated as REJECTED or APPROVAL_REQUIRED triggers the fail_gate task (io.kestra.plugin.core.execution.Fail), immediately terminating execution with a non-zero exit code to halt automated CI/CD deployment pipelines.

Ingestion Flexibility: Uploaded Artifact vs. HCL Planning

The blueprint supports two ingestion pathways:

  1. Direct JSON Plan Artifact (plan_file): Upload or pass an already-generated Terraform plan in JSON format (terraform show -json tfplan > plan.json). The blueprint evaluates the artifact directly without requiring cloud credentials or Terraform initialization.
  2. Inline HCL Configuration (terraform_code): Provide Terraform configuration code. The workspace initializes Terraform with the pinned hashicorp/terraform:1.9.8 Docker container and generates the plan automatically.

Actions and Replacements

Terraform plans express actions as arrays:

  • ["create"]: New resource addition.
  • ["update"]: In-place modification.
  • ["delete"]: Resource destruction.
  • ["delete", "create"] or ["create", "delete"]: Resource replacement (destroy then recreate). Replacements of stateful resources are categorized as CRITICAL risk because data loss can occur during recreate cycles.

Security & Sensitive Data Handling

Terraform execution plans can contain sensitive state attributes, environment variables, or secrets. To adhere to security best practices:

  • Raw plan.json files are never dumped into execution logs or Slack notifications.
  • The Python analyzer extracts only safe metadata (type, address, actions, classification).
  • Slack notifications and Markdown scorecards contain only sanitized risk metrics and aggregated summary tables.

CI/CD Pipeline Integration

Trigger this blueprint from GitHub Actions, GitLab CI, or Jenkins upon pull request creation:

curl -X POST "https://<your-kestra-host>/api/v1/executions/webhook/company.team/terraform-plan-risk-policy-gate/<TERRAFORM_PLAN_WEBHOOK_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": {
      "environment": "production",
      "max_allowed_deletions": 0,
      "blast_radius_rejection_threshold": 60,
      "fail_on_rejection": true,
      "notify_slack": true
    }
  }'

Prerequisites & Secrets

  • Container Engine: Docker or container runner accessible to Kestra when generating plans from terraform_code using hashicorp/terraform:1.9.8.
  • TERRAFORM_PLAN_WEBHOOK_KEY (required for Webhook trigger): Secret key securing the on_iac_plan_request Webhook trigger.
  • SLACK_WEBHOOK_URL (optional): Required only when notify_slack: true is enabled.
  • Cloud Provider Credentials (optional): When evaluating cloud infrastructure configurations via terraform_code, provide provider environment variables (such as AWS_ACCESS_KEY_ID, GOOGLE_APPLICATION_CREDENTIALS).
See How

New to Kestra?

Use blueprints to kickstart your first workflows.