
Terraform Wiz is one of the more common searches from teams trying to close the gap between the infrastructure they define in code and the infrastructure actually running in their cloud accounts. Wiz is best known as a cloud security platform, but it also scans Terraform and OpenTofu code directly, and its bigger differentiator is connecting that code back to the live resources it deploys.
This guide covers what Wiz does with Terraform, the three places it scans (your VCS repo, the Wiz CLI, and CI/CD or run task integrations), the misconfigurations it catches most often, and how its code-to-cloud graph works. Toward the end, we'll cover Scalr's native Wiz integration, which runs the scan automatically after a Terraform plan with no CI/CD wiring needed.
Wiz is a cloud-native application protection platform (CNAPP) that gives security teams a single view across cloud misconfigurations, vulnerabilities, identity risk, and exposed secrets. It connects to your cloud accounts (AWS, Azure, GCP, and others) using an agentless, API-based approach, then builds what Wiz calls a Security Graph: a map of every resource, how it's configured, what it's connected to, and who or what can reach it.
Where Wiz becomes relevant to Terraform specifically is that it doesn't stop at runtime. It also connects to your source code, so the same graph that shows a publicly exposed database can trace that database back to the Terraform resource block, the pull request, and the engineer who merged it.
Most cloud security incidents don't start with a sophisticated exploit. They start with a misconfigured resource: a security group open to the internet, a storage bucket without encryption, an IAM role with far more access than it needs. Terraform is how most teams provision that infrastructure now, which means Terraform code is also where those mistakes get introduced.
Scanning Terraform before it deploys is cheaper than fixing it after. A misconfiguration caught in a pull request is a one-line diff. The same misconfiguration caught after it's live in production is an incident, a remediation ticket, and possibly a compliance finding. That's the general case for Terraform vulnerability scanning, and it's exactly what Wiz is built to do for teams that already use it for cloud security posture management and want the same policy engine covering their IaC.
Wiz scans Terraform and OpenTofu in three places, and most teams end up using more than one.
Wiz connects to VCS providers like GitHub, GitLab, and Bitbucket and continuously scans the Terraform and OpenTofu files in the repositories you import. As Wiz indexes a repo, it resolves variables and modules so it understands the configuration as a whole rather than one file at a time, then flags misconfigurations directly against the code. This is the earliest point you can catch a problem, since it happens independent of any specific pipeline or plan.
The Wiz CLI (wizcli) runs the same scanning engine from a laptop, a CI/CD job, or any automation pipeline. It's the option to reach for when you want Terraform scanning enforced as a build step rather than relying on the VCS connector alone, or when your code lives somewhere Wiz doesn't have a native connector.
To get started, authenticate the CLI with a Wiz service account:
wizcli auth --id <client_id> --secret <client_secret>
Then run an IaC scan against a directory containing Terraform or OpenTofu files:
wizcli iac scan --path . --name <scan-name>
This works against a working directory of .tf files, and it also works against a Terraform plan converted to JSON, which lets you catch issues that only show up once variables and modules are resolved, not just in the raw HCL. Because the CLI is just a binary, it drops into any CI/CD system (GitHub Actions, GitLab CI, Jenkins) or any Terraform automation platform, including Scalr, the same way.
This is where Wiz differs from a pure static scanner like Checkov or tfsec. Once a Wiz connector is attached to your cloud account, Wiz uses the Terraform state file as a bridge between what's deployed and the code that deployed it. It resolves the resources in state back to the module and file that declared them, so when the Security Graph shows a live security finding, like an S3 bucket with public access, it also shows the exact Terraform file, line number, module, and commit author responsible.
That matters because most CNAPPs treat "code" and "runtime" as two separate problems with two separate tools. Wiz applies a single policy, like "S3 buckets must have Block Public Access enabled," consistently across code review, CI/CD, and the live environment, so a violation is caught the same way no matter which stage it's found in, and a runtime finding always has a remediation path back to a pull request instead of a manual console change.
The specific rule set is large, but most findings fall into a handful of recurring categories.
Security groups or firewall rules that expose a sensitive port to the entire internet are one of the most common and most severe findings.
# This security group allows SSH access from ANY IP address.
resource "aws_security_group" "allow_ssh" {
name = "allow-all-ssh"
description = "Allow SSH inbound traffic"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # DANGEROUS
}
}Resources that hold data, like S3 buckets, RDS instances, or EBS volumes, without encryption configured are flagged as a default risk, since it's a single missing block away from being fixed.
resource "aws_s3_bucket" "unencrypted_data" {
bucket = "my-company-sensitive-data-bucket"
acl = "private"
# Missing server-side encryption configuration
}IAM roles and policies that grant * actions or * resources instead of a scoped set of permissions show up constantly, especially in code copied from tutorials or generated quickly to unblock a deployment.
resource "aws_iam_policy" "overly_broad" {
name = "broad-access"
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "*"
Effect = "Allow"
Resource = "*" # DANGEROUS: grants access to everything
}]
})
}API keys, passwords, and tokens written directly into a .tf file or a variable default get stuck in version control history permanently, even if they're removed in a later commit. Wiz's secrets detection flags high-entropy strings and known key formats in both the VCS scan and the CLI scan.
A few practices consistently show up in how teams get the most out of pairing Wiz with Terraform:
If you're running Terraform or OpenTofu through Scalr, you don't need to wire the Wiz CLI into a separate CI/CD job. Scalr has a native Wiz integration that runs as a step in the run pipeline after the Terraform plan completes, and it can either route results to Scalr's own OPA policies or block the run automatically.
Before connecting Wiz to Scalr, you'll need:
create:security_scans permissionNote that Scalr supports one Wiz connection per account, and setting it up requires the integrations:manage permission.
Scalr's Wiz integration gives you two ways to act on scan results:
input.run_tasks.wiz in the post-plan policy input, so you can write custom OPA logic around it instead of relying on a simple pass/fail.Once enabled, the Wiz scan shows up as its own step in the run pipeline, and results are visible directly in the Scalr UI without leaving the platform to check a separate dashboard. Because the integration runs after the plan, it fits the same code-to-cloud model Wiz uses everywhere else: the plan output it scans reflects exactly what's about to be deployed.
Wiz gives you Terraform scanning in the same place you already track cloud security posture, and its biggest advantage over a pure static scanner is that a runtime finding maps back to the exact code and author that created it instead of leaving you to reverse-engineer the source. Whether you scan through the VCS connector, the CLI, or a run task, the goal is the same: catch the misconfiguration before it's a live resource instead of after.
If you want to go deeper on the surrounding topics:
This blog has been verified for Terraform and OpenTofu
