Getting Started with Terraform Vulnerability Scanning
Terraform vulnerability scanning is the practice of automatically analyzing infrastructure code to find & fix security issues before they reach production.
Terraform vulnerability scanning is the practice of automatically analyzing your infrastructure code to find and fix security issues before they ever reach a production environment. It's a foundational practice for any team serious about cloud security. This guide provides a straightforward look at the most common vulnerabilities, the tools available to find them, and how to integrate them into your workflow.
Scanning Catches Misconfigurations
The most common risks in Terraform aren't complex hacks; they are preventable misconfigurations. These simple errors can lead to major security breaches. Here are some of the most frequent issues scanners are designed to catch.
Catch Insecure Network Access
One of the most common mistakes is creating a firewall rule or security group that exposes a sensitive port, like SSH (22), to the entire internet.
Insecure HCL Example:
# 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
}
}
A scanner will immediately flag 0.0.0.0/0
as a high-severity issue, pushing you to restrict the IP range to a known, trusted source.
Catch Hardcoded Secrets
Embedding secrets like API keys or passwords directly in your code is a critical failure. If this code is committed to a version control system, the secret is permanently exposed in the repository's history.
Insecure HCL Example:
# A hardcoded password in a variable default.
variable "db_password" {
description = "Database admin password"
type = string
default = "SuperSecretPassword123!" # DANGEROUS
}
resource "aws_db_instance" "default" {
# ... other configuration
password = var.db_password
}
Scanners are adept at detecting high-entropy strings and common key formats, preventing them from being saved. The correct approach is to use a dedicated secrets manager like AWS Secrets Manager or HashiCorp Vault.
Catch Unencrypted Data Storage
Failing to enable encryption for resources that store data, like S3 buckets or databases, can leave sensitive information vulnerable.
Insecure HCL Example:
# This S3 bucket is created without server-side encryption enabled.
resource "aws_s3_bucket" "unencrypted_data" {
bucket = "my-company-sensitive-data-bucket"
acl = "private"
# Missing encryption configuration
}
A security scanner will detect the absence of an encryption block and guide you to add the necessary configuration.
The Open-Source Scanning Toolkit
The good news is that a mature ecosystem of powerful, open-source tools exists to detect these and hundreds of other issues. Most are backed by commercial security companies and serve as the "core" of their larger platforms.
Here’s a comparison of the leading tools:
Feature | tfsec | Checkov | Terrascan | Trivy |
---|---|---|---|---|
Primary Focus | Terraform-Specific Security | Multi-Framework IaC Security | Multi-Framework IaC & Compliance | Unified Scanning (Containers, IaC, Secrets) |
Backing Vendor | Aqua Security | Palo Alto Networks | Tenable | Aqua Security |
Key Differentiator | Speed, simplicity, Terraform-native focus | Graph-based analysis for contextual awareness | Native OPA/Rego engine, drift detection | Single CLI for multiple security scanning tasks |
Policy Language(s) | Rego, JSON, YAML | Python, YAML | Rego | Rego |
Scans Plan File? | Yes | Yes | Yes | Yes |
Automating Security Scanning in CI/CD
To be effective, scanning must be automated. The best place to do this is in your Continuous Integration/Continuous Deployment (CI/CD) pipeline. This creates a security gate that automatically checks every code change.
Here is a practical example of how to use Checkov within a GitHub Actions workflow. This workflow runs on every pull request, scans the code, and uploads the results so they appear directly on the pull request.
name: Terraform IaC Security Scan
# This workflow runs on every pull request that targets the main branch
on:
pull_request:
branches: [ main ]
jobs:
checkov-scan:
runs-on: ubuntu-latest
steps:
# Step 1: Check out the repository's code
- name: Checkout code
uses: actions/checkout@v3
# Step 2: Set up Python, which Checkov needs to run
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9
# Step 3: Install the Checkov scanner
- name: Install Checkov
run: pip install checkov
# Step 4: Run the scan on the current directory (-d .)
# The job will fail if Checkov finds any issues.
# It outputs results in the SARIF format for GitHub to display.
- name: Run Checkov scan
run: checkov -d . --output sarif --output-file-path results.sarif
# Step 5: Upload the SARIF file to GitHub Advanced Security
# This step runs even if the scan fails, ensuring results are always visible.
- name: Upload SARIF file
if: always()
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: results.sarif
.github/workflows/security_scan.yml
With this workflow in place, any attempt to merge code with a security misconfiguration will be blocked, with clear feedback provided directly to the developer in the pull request.
More Reading
Terraform vulnerability scanning is an essential part of the modern development lifecycle. By integrating automated scanners into your CI/CD pipeline, you can catch and fix security misconfigurations early, allowing your team to build and deploy cloud infrastructure with both speed and confidence.
If interested in deepening your understanding of security tooling for Terraform, see here:
