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.
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:
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
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
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/0on 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:
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.
In This Article
- Introduction
- What Is a Plan File?
- Why Scan Plan Files
- How TFGaurd Does It
- CI/CD Integration
- What TFGaurd Catches
- Web Dashboard
- Best Practices
- Conclusion