terrascan scan: Policy Scan IaC in CI
terrascan scan detects security and compliance violations in IaC using Rego policies, exiting 3 by default when any violation is found.
Terrascan is a policy-as-code scanner for Terraform, Kubernetes, Helm, Dockerfile, and more. It uses a bundled Rego policy set (extensible with your own) and is built to run as a PR gate that blocks misconfigured infrastructure.
What it does
terrascan scan detects the IaC type (or you set it with -i), loads policies for the target cloud/type, and reports violations with rule id, severity, and location. Its exit code encodes the result: 0 clean, 3 when violations are found (1 for a runtime error, 4 for both).
Common usage
# scan the current directory (auto-detect Terraform)
terrascan scan
# scan Kubernetes manifests explicitly
terrascan scan -i k8s -d ./manifests
# JSON output for a specific cloud policy set
terrascan scan -i terraform -t aws -o jsonOptions
| Flag | What it does |
|---|---|
| -i, --iac-type <type> | IaC type: terraform, k8s, helm, kustomize, dockerfile |
| -t, --policy-type <cloud> | Cloud policy set: aws, azure, gcp, github, k8s |
| -d, --iac-dir <path> | Directory of IaC to scan |
| -p, --policy-path <path> | Custom Rego policy directory |
| -o, --output <fmt> | Output: human, json, yaml, sarif, junit-xml |
| --config-only | Emit normalized config without evaluating policies |
In CI
Set -i and -t explicitly for deterministic results, use -o sarif for code scanning, and treat exit 3 as the gate. Because a runtime error is exit 1 and a scan with violations is exit 3, do not just test for non-zero if you want to distinguish "found issues" from "tool broke". Policies are Rego and run offline once the policy repo is cached.
Common errors in CI
A scan with findings ends with a "Violation Details" list (rule name, severity, resource, file/line) and exit code 3. "no policies found" or "error while downloading policies" means the policy cache is missing; run once to fetch or pin -p to a vendored path. "error: unsupported iac type" means -i is wrong for the files present.