Secure HashiCorp Terraform Code with cnspec
Scan Terraform configurations, plans, and state files for security misconfigurations with cnspec.
Prevent insecure infrastructure from being provisioned by scanning Terraform before it applies. cnspec evaluates HCL configurations, plan files, and state files against security policies on a developer workstation, as a CI/CD gate, or as a post-provisioning check after terraform apply.
Mondoo's cloud security policies (AWS, Azure, Google Cloud) include IaC variants that run against Terraform code, so the same checks that evaluate your live cloud accounts also evaluate the infrastructure as code that defines them. Mondoo additionally ships the Terraform Deprecations policy to flag use of deprecated Terraform providers and resources.
Prerequisites
To scan Terraform code with cnspec, you must have:
- cnspec installed on your workstation
- Terraform configuration files to scan (HCL, plan, or state)
Scan Terraform code
Scan HCL configuration files in a directory:
cnspec scan terraform /path/to/terraform/Scan a Terraform plan file:
terraform plan -out tfplan.binary
terraform show -json tfplan.binary > tfplan.json
cnspec scan terraform plan tfplan.jsonScan a Terraform state file:
cnspec scan terraform state terraform.tfstatecnspec returns the results to stdout. If you're logged into Mondoo Platform, results are also reported there.

Scan with Mondoo Terraform policies
Mondoo's cloud security policies (AWS Security, Azure Security, Google Cloud Security) include Terraform variants of every check, so the same controls that evaluate your live cloud accounts also evaluate the infrastructure as code that defines them.
Mondoo Platform users: Enable the cloud policy that matches your target. In the Mondoo Console, go to Findings > Policies, search for "AWS", "Azure", or "Google Cloud", and add the policy. All future Terraform scans automatically evaluate against the Terraform variants. To learn more, read Manage Policies.
Mondoo also ships a standalone Terraform Deprecations policy that flags use of deprecated Terraform providers and resources. Search for "Terraform" in Findings > Policies to add it.
Open source users: The cloud-policy Terraform variants ship inside the open source cloud bundles in mondoohq/cnspec/content. Point cnspec at the matching bundle when you scan, for example AWS:
cnspec scan terraform /path/to/terraform/ \
--policy-bundle https://raw.githubusercontent.com/mondoohq/cnspec/refs/heads/main/content/mondoo-aws-security.mql.yamlYou can also pin just the standalone Terraform Deprecations bundle:
cnspec scan terraform /path/to/terraform/ \
--policy-bundle https://raw.githubusercontent.com/mondoohq/cnspec/refs/heads/main/content/terraform-deprecations.mql.yamlExplore Terraform configurations
Open a cnspec shell to discover resources and try out checks:
cnspec shell terraform /path/to/terraform/List Terraform files
cnspec> terraform.files
terraform.files: [
0: terraform.file path="main.tf"
1: terraform.file path="variables.tf"
...
]List all resources
cnspec> terraform.resources
terraform.resources: [
0: terraform.resource type="aws_instance" nameLabel="web"
1: terraform.resource type="aws_s3_bucket" nameLabel="data"
...
]List modules
cnspec> terraform.modulesRetrieve variables from tfvars files
cnspec> terraform.tfvarsFilter resources by type
Find all AWS S3 bucket resources:
cnspec> terraform.resources.where(type == "aws_s3_bucket")Explore plan-file resource changes
When querying a plan file:
cnspec> terraform.plan.resourceChangesExplore state-file resources
When querying a state file:
cnspec> terraform.state.resourcesExample: Ensure AWS S3 buckets use server-side encryption
This check verifies that every aws_s3_bucket resource defines a server_side_encryption_configuration rule with apply_server_side_encryption_by_default:
terraform.resources.where(nameLabel == 'aws_s3_bucket') {
blocks {
blocks.one(_.type == "rule" && _.blocks.one(type == 'apply_server_side_encryption_by_default'))
}
}The query targets aws_s3_bucket resources, walks into the nested server_side_encryption_configuration and rule blocks, and asserts that an apply_server_side_encryption_by_default block is present.
Post-provisioning scans
cnspec also fits as a local-exec step at the end of a terraform apply, so the same policies that gate your cloud account also evaluate freshly-provisioned hosts. For example:
resource "aws_instance" "web" {
# ...launch and provisioning configuration...
provisioner "local-exec" {
command = "cnspec scan ssh ubuntu@${self.public_ip} -i ${var.private_key} --risk-threshold 90"
}
}--risk-threshold 90 makes the build fail if the scan score drops below 90.
Learn more
- Terraform Resource Pack Reference: every Terraform resource and field cnspec can query
- Write Effective MQL: guide to authoring checks and queries