Terraform Plan Security

How to Scan Terraform Plan Files for Security Issues Before Apply

Running terraform apply without scanning the plan is like deploying code without tests. Here's exactly how TFGaurd catches dangerous changes before they hit your cloud.

April 4, 2026 TFGaurd Team 10 min read Terraform Plan · Security · CI/CD

Every day, DevOps teams around the world run terraform apply on plan files they've never security-checked. The result? Unencrypted databases, public S3 buckets, and wide-open security groups reaching production in seconds.

The solution is simple: scan Terraform plan files before you apply them. A Terraform plan file contains the exact set of changes that will be made to your infrastructure — new resources, modified attributes, and deletions. Scanning these changes (not just the raw HCL source) gives you the highest-fidelity security feedback possible because plans resolve variables, modules, and data sources into concrete values.

Key Insight: Static HCL scanning catches around 80% of misconfigurations. Plan-file scanning catches the remaining 20% — including issues hidden behind variable interpolation, module outputs, and conditional expressions.

What Is a Terraform Plan File?

When you run terraform plan, Terraform computes the difference between your desired state (HCL code) and the actual state of your cloud. The output — the plan file — is a structured description of every resource that will be created, updated, or destroyed.

Binary Plan vs. JSON Plan

By default, terraform plan -out=tfplan produces a binary file that only Terraform itself can read. To scan it with external tools, you first convert it to JSON:

Shell # 1. Generate the binary plan terraform plan -out=tfplan # 2. Convert to machine-readable JSON terraform show -json tfplan > tfplan.json

The JSON output is a rich document containing resource_changes, planned_values, and prior_state. Security scanners like TFGaurd parse this JSON to evaluate every proposed change against a library of security rules.

Why You Must Scan Terraform Plan Files

Scanning raw .tf files is important — but it's not enough. Here's why plan-file scanning is the gold standard:

Dimension HCL Source Scan Plan File Scan
Variable Resolution Sees var.enable_encryption Sees the resolved value: false
Module Outputs Cannot trace cross-module values All module outputs are expanded
Conditional Logic Sees both branches of count Knows exactly which resources will exist
Data Sources Cannot evaluate Fetches real values from provider
Accuracy ~80% of issues caught ~98% of issues caught

Real-World Example: A module sets publicly_accessible = var.public_db on an RDS instance. During HCL scanning, the variable is opaque. During plan scanning, TFGaurd sees the resolved value is true — and blocks the deploy.

How TFGaurd Scans Terraform Plan Files

TFGaurd was built from day one to scan Terraform plan files alongside raw HCL. Whether you're using the web dashboard, the CLI, or a CI/CD pipeline, the workflow is the same:

1 Generate Plan JSON

Run your standard Terraform workflow to produce a plan, then export the JSON representation. TFGaurd never needs access to your cloud credentials — it only reads the plan JSON.

2 Submit to TFGaurd

Upload the tfplan.json file via the web UI drag-and-drop zone, or pipe it directly through the CLI. TFGaurd parses the resource_changes array and builds an in-memory resource graph.

3 Rule Evaluation

Each planned resource change is evaluated against TFGaurd's library of 1200+ security rules covering AWS, GCP, Azure, and Oracle. Rules check the after state — the exact configuration that will exist post-apply.

4 Instant Verdict

TFGaurd returns a pass/fail verdict in under 2 seconds. Every violation includes the resource address, severity level, a human-readable explanation, and the exact fix.

CLI Example

Shell # Generate plan JSON terraform plan -out=tfplan terraform show -json tfplan > tfplan.json # Scan the plan file with TFGaurd CLI tfgaurd scan --file tfplan.json # Output: ✓ Parsed 24 resource changes from plan file [CRITICAL] aws_db_instance.production RDS instance does not have encryption at rest enabled Fix: Set storage_encrypted = true [CRITICAL] aws_security_group.web_sg Security group allows SSH (port 22) from 0.0.0.0/0 Fix: Restrict cidr_blocks to your corporate IP range [HIGH] aws_s3_bucket.data_lake S3 bucket does not have versioning enabled Fix: Add versioning { enabled = true } ━━━ Scan complete: 3 violations (2 critical, 1 high) ━━━

Scan Terraform Plan Files in CI/CD

The most powerful use of plan scanning is inside your CI/CD pipeline. TFGaurd integrates into GitHub Actions, GitLab CI, Jenkins, and any runner that can execute shell commands.

GitHub Actions Example

YAML — GitHub Actions name: Terraform Security Gate on: [pull_request] jobs: plan-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Terraform uses: hashicorp/setup-terraform@v3 - name: Terraform Init & Plan run: | terraform init terraform plan -out=tfplan terraform show -json tfplan > tfplan.json - name: Install TFGaurd CLI run: curl -sSL https://tfgaurd.com/install.sh | bash - name: Scan Terraform Plan File run: tfgaurd scan --file tfplan.json --fail-on high

The --fail-on high flag makes the pipeline exit with a non-zero code if any High or Critical violations are found — effectively blocking the merge until the issues are resolved.

Privacy First: TFGaurd CLI runs entirely locally. Your plan JSON never leaves the CI runner. No cloud uploads, no SaaS middlemen, zero data persistence.

What TFGaurd Catches When You Scan Plan Files

TFGaurd's plan scanner evaluates every resource_changes[].change.after block against 1200+ security rules. Here are the most common categories of issues caught:

  • Unencrypted Storage & Databases — S3 buckets without SSE-KMS, RDS without storage_encrypted, EBS volumes in plaintext.
  • Open Network Access — Security groups with 0.0.0.0/0 on SSH, RDP, or database ports. Public subnets without NAT gateways.
  • Missing Logging & Monitoring — CloudTrail disabled, VPC Flow Logs absent, access logging turned off on ALBs.
  • Overly Permissive IAM — Policies with * actions or resources, missing condition keys, inline vs. managed policy violations.
  • Public Endpoints — RDS publicly_accessible = true, Elasticsearch domains outside VPC, public EKS API endpoints.
  • Compliance Gaps — Missing mandatory tags, non-compliant backup retention, missing deletion protection on production databases.

Example: Catching a Resolved Variable

Consider this HCL code:

HCL variable "db_encryption" { default = false # Dangerous default! } resource "aws_db_instance" "main" { engine = "postgres" storage_encrypted = var.db_encryption }

A source-only scanner sees var.db_encryption and cannot determine whether encryption is on or off. But when you scan the Terraform plan file, TFGaurd sees the resolved value: "storage_encrypted": false — and immediately flags a Critical violation.

Scan Plan Files via the Web Dashboard

Not everyone lives in the terminal. TFGaurd's web dashboard at tfgaurd.com lets you drag-and-drop your tfplan.json file and get instant results with a visual breakdown:

  • Severity Heatmap — Instantly see how many Critical, High, Medium, and Low issues exist.
  • Resource-Level Details — Click any resource to see the exact attribute that triggered the violation.
  • Fix Suggestions — Every finding includes the exact HCL change needed to remediate.
  • Export — Download findings as JSON, CSV, or a compliance-ready PDF report.

Zero Setup: No account required for your first scan. Just drag your Terraform plan file onto the upload zone and see results in under 2 seconds.

Best Practices for Plan File Scanning

1. Always Scan Both Source and Plan

Source scanning catches structural issues early (in the IDE or pre-commit hooks). Plan scanning catches runtime-resolved issues. Use both layers for maximum coverage.

2. Gate Deploys on Plan Scan Results

Configure your pipeline so that terraform apply only runs if the plan scan passes. This is the single most impactful security measure you can implement.

3. Scan on Every Pull Request

Don't just scan on the main branch. Run plan scans on every PR so developers get immediate feedback and can fix issues before code review even starts.

4. Use Severity Thresholds

Block merges on Critical and High issues, but allow Medium and Low to pass with warnings. This avoids developer fatigue while keeping your security bar high.

5. Review Plan Diffs, Not Just Source Diffs

A 1-line source change can produce a 50-resource plan diff (e.g., changing a module version). Always review the plan output to understand the true blast radius.

Conclusion

If you're only scanning raw HCL source files, you're leaving a significant security gap. The Terraform plan file is the most accurate representation of what will actually be deployed to your cloud — and scanning it is the single best way to prevent misconfigurations from reaching production.

TFGaurd makes it trivial to scan Terraform plan files. Whether you prefer the CLI, the web dashboard, or a CI/CD pipeline integration, the workflow is identical: generate plan JSON → scan with TFGaurd → fix issues → apply with confidence.

Stop deploying blind. Start scanning your Terraform plan files today.

🛡️ Scan Your First Terraform Plan File — Free

Drop your tfplan.json into TFGaurd and get instant results. Zero setup. Zero data persistence.

Try TFGaurd Free