Skip to content

title: CloudSlash - Terraform Diff Scanning Reference description: CloudSlash can scan a terraform plan output before apply: catching waste and policy violations before they reach infrastructure. Traditional infrastructure s...


Terraform Diff Scanning

CloudSlash can scan a terraform plan output before apply: catching waste and policy violations before they reach infrastructure.

Note

Traditional infrastructure scanners analyze the current live cloud state. The plan diff scanner inverts this model: it analyzes the Terraform execution plan before apply, surfacing violations against resources that are about to be created, modified, or destroyed. This document details the architecture of the plan parser, CRN derivation, and integration with the heuristic and policy evaluation pipelines.


Problem Statement

A standard cs scan queries live cloud APIs and evaluates the full account state. That's reactive: waste gets discovered after resources are provisioned and already incurring cost.

Shift-left requires pre-merge analysis. When Terraform generates a plan during a pull request, the planned changes contain enough information to catch violations before they reach production.

Plan JSON Structure

Terraform exposes the plan via terraform show -json:

terraform plan -out=tfplan.out
terraform show -json tfplan.out > tfplan.json

The JSON contains a resource_changes[] array. Each element describes a single resource mutation:

{
  "address": "aws_instance.web_server",
  "type": "aws_instance",
  "name": "web_server",
  "provider_name": "registry.terraform.io/hashicorp/aws",
  "change": {
    "actions": ["create"],
    "after": {
      "ami": "ami-0abcdef1234567890",
      "instance_type": "m5.xlarge",
      "region": "us-east-1",
      "tags": {"env": "production"}
    }
  }
}

Parser Architecture

The CloudSlash plan parser uses hashicorp/terraform-json for type-safe deserialization: the same library used by Terraform Cloud, Spacelift, and env0.

Provider Inference

The provider_name field (e.g., registry.terraform.io/hashicorp/aws) decomposes to extract the canonical provider identifier:

Provider Name Resolved
registry.terraform.io/hashicorp/aws aws
registry.terraform.io/hashicorp/google gcp
registry.terraform.io/hashicorp/azurerm azure
registry.terraform.io/hashicorp/kubernetes k8s

Region Extraction

The parser extracts region from planned values in this order:

  1. Check after.region (AWS standard)
  2. Check after.location (Azure, GCP)
  3. Check after.zone (GCP zonal resources)
  4. Default to unknown if not determinable

Service Mapping

The Terraform resource type (e.g., aws_instance) decomposes into a service category and resource type:

Terraform Type Service Resource Type
aws_instance ec2 instance
aws_s3_bucket s3 s3_bucket
aws_db_instance rds db_instance
aws_lambda_function lambda lambda_function
aws_security_group vpc security_group
google_compute_instance compute compute_instance

Graph Construction

Each resource_change with a non-noop action materializes as a node in the Devi Universal Graph. The node receives a CRN derived from the provider, region, service, and Terraform address.

Resources with delete or replace actions are automatically flagged:

  • is_waste = true
  • waste_reason = "terraform_destroy"
  • risk_score = 60

This ensures the heuristic and CEL policy engines evaluate destruction operations with elevated scrutiny.

Pipeline Integration

The plan-scoped graph flows through the same analysis pipeline as a full scan:

Plan JSON → Parser → Graph → Heuristics → CEL Policies → Formal Verification → Report

Output formats (SARIF, JSON, GitHub PR, table) are identical. The only difference is scope: the graph contains only planned changes, not the full account state.

cs scan --plan=tfplan.json --format=sarif --output=results.sarif --fail-on=critical --rules soc2-compliance.yaml