Terrascan: Multi-Cloud IaC Security Scanning with OPA Rego (Now Archived)
Hook
Tenable built one of the most comprehensive IaC security scanners with support for six different infrastructure formats and 500+ policies—then archived it. Here's what made it powerful and what that means for your security pipeline.
Context
Infrastructure as Code revolutionized cloud deployments, but it also created a new attack surface: misconfigured resources committed directly to version control. A single terraform apply with overly permissive S3 buckets or exposed database ports could compromise an entire environment. Traditional security scanning happened too late—after resources were provisioned and already exposed.
Terrascan emerged to shift security left by analyzing IaC files before deployment. Unlike point solutions focused solely on Terraform or Kubernetes, Terrascan aimed for comprehensive coverage: Terraform HCL2, CloudFormation, Kubernetes manifests, Azure ARM templates, Helm charts, and even Dockerfiles. Built by Tenable (the vulnerability management company behind Nessus), it brought enterprise security thinking to the IaC problem. The tool leveraged Open Policy Agent's Rego language to encode compliance frameworks like CIS benchmarks, PCI-DSS, and HIPAA into machine-readable policies. However, as of 2024, Tenable has archived the repository, ending active development while leaving behind a substantial open-source legacy.
Technical Insight
Terrascan's architecture centers on a normalize-then-evaluate pattern that handles multiple IaC formats through a unified scanning pipeline. When you run a scan, Terrascan first parses the input files (whether HCL, YAML, or JSON) into a standardized intermediate representation—a JSON structure that abstracts away format-specific syntax. This normalization layer is crucial: it allows a single policy to detect misconfigurations across Terraform, CloudFormation, and Kubernetes without rewriting logic for each format.
The policy engine uses Open Policy Agent's Rego language, which excels at expressing complex compliance rules. Here's a real example of a Terrascan policy that detects unencrypted AWS EBS volumes:
package accurics
default ebs_encryption_enabled = false
ebs_encryption_enabled = true {
volume := input.aws_ebs_volume[_]
volume.config.encrypted == true
}
default ebs_snapshot_encryption = false
ebs_snapshot_encryption = true {
snapshot := input.aws_ebs_snapshot[_]
snapshot.config.encrypted == true
}
violation[msg] {
volume := input.aws_ebs_volume[_]
volume.config.encrypted != true
msg := sprintf("EBS volume '%s' is not encrypted", [volume.name])
}
This declarative approach means policies read almost like documentation. The input object contains the normalized IaC configuration, and rules query against it using Rego's pattern matching. The violation block defines what constitutes a policy failure and generates human-readable error messages.
Terrascan's CLI integrates cleanly into CI/CD workflows with flags that control behavior. The --policy-type flag filters which policies run (security, compliance, or both), while --severity filters by critical, high, medium, or low. The --output flag supports multiple formats including JSON for downstream processing:
terrascan scan -i terraform -d ./infrastructure \
--policy-type security \
--severity high \
--output json > scan-results.json
One architectural decision that distinguishes Terrascan is its remote policy management. Instead of bundling all 500+ policies in the binary, it downloads them on first run from GitHub. This keeps the binary small but introduces a dependency on network connectivity. You can override this with --policy-path to use local policy directories—critical for air-gapped environments or when you've forked policies for customization.
The tool also supports server mode, where Terrascan runs as an HTTP API that accepts IaC files via POST requests. This enables centralized scanning where multiple teams submit configurations to a shared security service:
terrascan server --port 8080
# In another terminal
curl -X POST -H "Content-Type: application/json" \
-d @terraform-files.json \
http://localhost:8080/v1/terraform/v14/local/scan
For Kubernetes-native workflows, Terrascan supports admission controller integration via a validating webhook. When deployed in your cluster, it intercepts kubectl apply commands and blocks deployments that violate policies—runtime enforcement that catches misconfigurations even when developers bypass CI/CD.
The container vulnerability scanning feature deserves special mention. Terrascan doesn't just analyze IaC definitions; it can inspect Docker images referenced in your configurations and scan them for CVEs by integrating with registry APIs. This unified approach means a single tool checks both infrastructure configuration and container security, reducing tool sprawl in your pipeline.
Gotcha
The elephant in the room is that Terrascan is archived. Tenable stopped maintaining it in 2024, meaning no new policies for emerging cloud services, no fixes for newly discovered parsing bugs, and no security patches if vulnerabilities are found in dependencies. This is particularly concerning for a security tool. While the existing policy library remains valuable and the code is still functional, you're inheriting technical debt the moment you adopt it. You'll need to fork the repository and commit to maintaining it yourself or accept that it will gradually become stale.
Beyond the archival status, Terrascan's default behavior of exiting with non-zero codes on policy violations can break CI/CD pipelines in frustrating ways. If you're incrementally adopting IaC security scanning on a repository with existing violations, your builds will start failing immediately. You need to carefully tune severity thresholds, use --skip-rules to ignore specific policies during rollout, or configure your pipeline to treat Terrascan failures as warnings initially. There's no built-in concept of a grace period or progressive enforcement. The policy initialization step also requires either internet access to GitHub or pre-cached policies in your container images. In locked-down environments, this necessitates running terrascan init --policy-path ./policies and committing policies alongside your code, which bloats repositories. Finally, the error messages, while generally helpful, sometimes lack context about why a configuration violates a policy beyond stating that it does—you often need to read the Rego source to understand the rationale behind complex compliance rules.
Verdict
Use if: You're already running Terrascan in production and have the expertise to maintain a fork, or you need its specific combination of multi-cloud support and OPA Rego policies for an isolated project where updates aren't critical. The existing policy library is genuinely comprehensive and can provide immediate value if it matches your compliance requirements. Skip if: You're starting a new project or lack resources to maintain an archived codebase. For greenfield work, choose actively maintained alternatives like Checkov (broader policy support, active community), Trivy (fast, modern, covers IaC plus containers and VMs), or tfsec (if you're Terraform-focused). The security landscape evolves too rapidly to bet on unmaintained tools unless you're prepared to become the maintainer.