TrademarkTrademark
Features
Documentation

Using Checkov with Terraform - Integrations, Features, Examples

Learn the basics of how and when to use Checkov
Ryan FeeMarch 6, 2026Updated March 31, 2026
Using Checkov with Terraform - Integrations, Features, Examples
Key takeaways
  • Checkov is an open-source static analysis tool that scans IaC such as Terraform, CloudFormation, and Kubernetes to catch misconfigurations and security vulnerabilities before deployment.
  • It ships with hundreds of built-in policies covering frameworks like CIS, HIPAA, PCI DSS, and SOC2, and supports custom policies written in YAML.
  • You install Checkov via pip or brew and run it with commands like checkov -f main.tf, with flags to skip checks, target specific checks, set output formats, or soft-fail.
  • Scalr has a native Checkov integration that scans Terraform or OpenTofu code before the plan runs and can hard-fail to block non-compliant runs.
  • Scalr also supports enforcing custom Checkov policies from VCS repositories and running multiple Checkov versions on one environment to plan upgrades safely.

What is Checkov

Checkov is an open-source static code analysis tool for infrastructure-as-code (IaC) security. Bridgecrew built it, and Palo Alto Networks later acquired Bridgecrew. It scans cloud infrastructure configurations written in Terraform, CloudFormation, Kubernetes, Dockerfile, and ARM templates, then flags misconfigurations and security vulnerabilities before deployment. The checks run against predefined policies that catch the usual problems: unencrypted storage, too many permissions, open security groups, publicly exposed resources. Since it plugs into CI/CD pipelines and tells you how to fix what it finds, teams use it to move security earlier in development instead of auditing after the fact.

This post focuses on the Terraform and OpenTofu side of Checkov. Scalr has a native integration with Checkov, which we cover at the bottom.

Why is Checkov Needed?

Most infrastructure-as-code security incidents don't start with a clever attack. They start with a misconfigured resource: an unencrypted database, an IAM role that grants too much, a storage bucket left open. As more teams adopt IaC, those gaps multiply. Checkov scans your configuration files early in development and catches the problems before they reach production, where a single misconfiguration can turn into a data breach or a compliance violation. Fixing an issue in a pull request is also far cheaper than fixing it after it ships. Running the same checks on every change keeps your infrastructure aligned with standards like CIS, HIPAA, and SOC2 over time.

Key Checkov Features

  • Multi-IaC Support: Checkov scans infrastructure as code across multiple platforms including Terraform, CloudFormation, Kubernetes, Dockerfile, ARM Templates, and Serverless Framework. This unified scanning approach allows organizations to maintain consistent security policies regardless of which IaC tool is preferred.
  • Extensive Policy Library: Out of the box, Checkov includes hundreds of pre-built policies covering security best practices, compliance frameworks (CIS, HIPAA, PCI DSS, SOC2), and cloud provider-specific guidelines. These policies are continuously updated to address new security threats and cloud service features. This helps with quick adoption for organizations that are finding it difficult to write policy as code.
  • Custom Policy Framework: Organizations can define their own security policies. This allows security teams to codify company-specific requirements for their Terraform deployments.
  • CI/CD Integration: Checkov can be integrated with CI/CD platforms like GitHub Actions, GitLab CI, Jenkins, and Azure DevOps, but this does require some effort by the platform team depending on the use case. Scalr, a Terraform Automation and Collaboration platform, has an out-of-the-box integration with Checkov, as shown below. Failed security checks can automatically block Terraform plans from executing, enforcing security guardrails throughout the development lifecycle.

Using Checkov with Terraform

First, you’ll want to install Checkov using pip or brew. The full instructions are here.

To understand the basics of Checkov, let’s create a small Terraform module with a few deliberate security holes in it. Save the following Terraform file as main.tf:

provider "aws" {   region = "us-west-2" }

resource "aws_s3_bucket" "example" {   bucket = "my-example-bucket" }

resource "aws_s3_bucket_public_access_block" "example" {   bucket = aws_s3_bucket.example.id

  block_public_acls       = false   block_public_policy     = false   ignore_public_acls      = false   restrict_public_buckets = false }

This Terraform configuration file creates an AWS S3 bucket but deliberately has security issues (all public access controls are disabled).

Now, run the following command against this Terraform file:

checkov -f main.tf

The output will look something like this:

   ___| |__   ___  ___| | _______   __   / __| '_ \ / _ \/ __| |/ / _ \ \ / /  | (__| | | |  __/ (__|   < (_) \ V /   \___|_| |_|\___|\___|_|\_\___/ \_/

By Prisma Cloud | version: 3.2.380

terraform scan results:

Passed checks: 2, Failed checks: 4, Skipped checks: 0

Check: CKV_AWS_41: "Ensure no hard coded AWS access key and secret key exists in provider"   PASSED for resource: aws.default   File: /main.tf:1-3   Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/secrets-policies/bc-aws-secrets-5

Check: CKV_AWS_93: "Ensure S3 bucket policy does not lockout all but root user. (Prevent lockouts needing root account fixes)"   PASSED for resource: aws_s3_bucket.example   File: /main.tf:5-7   Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/bc-aws-s3-24

Check: CKV_AWS_53: "Ensure S3 bucket has block public ACLS enabled"   FAILED for resource: aws_s3_bucket_public_access_block.example   File: /main.tf:9-16   Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/bc-aws-s3-19

    9  | resource "aws_s3_bucket_public_access_block" "example" {     10 |   bucket = aws_s3_bucket.example.id     11 |     12 |   block_public_acls       = false     13 |   block_public_policy     = false     14 |   ignore_public_acls      = false     15 |   restrict_public_buckets = false     16 | }

Check: CKV_AWS_54: "Ensure S3 bucket has block public policy enabled"   FAILED for resource: aws_s3_bucket_public_access_block.example   File: /main.tf:9-16   Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/bc-aws-s3-20

    9  | resource "aws_s3_bucket_public_access_block" "example" {     10 |   bucket = aws_s3_bucket.example.id     11 |     12 |   block_public_acls       = false     13 |   block_public_policy     = false     14 |   ignore_public_acls      = false     15 |   restrict_public_buckets = false     16 | }

Check: CKV_AWS_55: "Ensure S3 bucket has ignore public ACLs enabled"   FAILED for resource: aws_s3_bucket_public_access_block.example   File: /main.tf:9-16   Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/bc-aws-s3-21

    9  | resource "aws_s3_bucket_public_access_block" "example" {     10 |   bucket = aws_s3_bucket.example.id     11 |     12 |   block_public_acls       = false     13 |   block_public_policy     = false     14 |   ignore_public_acls      = false     15 |   restrict_public_buckets = false     16 | }

Check: CKV_AWS_56: "Ensure S3 bucket has 'restrict_public_buckets' enabled"   FAILED for resource: aws_s3_bucket_public_access_block.example|   File: /main.tf:9-16   Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/bc-aws-s3-22

    9  | resource "aws_s3_bucket_public_access_block" "example" {     10 |   bucket = aws_s3_bucket.example.id     11 |     12 |   block_public_acls       = false     13 |   block_public_policy     = false     14 |   ignore_public_acls      = false     15 |   restrict_public_buckets = false     16 | }

Checkov has identified several security issues with the Terraform code:

  • Public access is not blocked
  • Ignore public ACLS is not blocked
  • Public ACLs are not blocked
  • Public policies are not blocked

To fix these issues, update your terraform file to include proper security configurations:

provider "aws" {   region = "us-west-2" }

resource "aws_s3_bucket" "example" {   bucket = "my-example-bucket" }

resource "aws_s3_bucket_versioning" "example" {   bucket = aws_s3_bucket.example.id   versioning_configuration {     status = "Enabled"   } }

resource "aws_s3_bucket_logging" "example" {   bucket = aws_s3_bucket.example.id

  target_bucket = aws_s3_bucket.example.id   target_prefix = "log/"

}

resource "aws_s3_bucket_public_access_block" "example" {   bucket = aws_s3_bucket.example.id

  block_public_acls       = true   block_public_policy     = true   ignore_public_acls      = true   restrict_public_buckets = true

}

Execute Checkov against the main.tf file again to verify the updates worked.

Advanced Commands and Use Cases

Here are some advanced Checkov commands for finer control over what you scan and how Checkov reports it, for both Terraform and OpenTofu:

Advanced Filtering and Targeting

# Skip specific checks checkov -f main.tf --skip-check CKV_AWS_18,CKV_AWS_21

# Check only specific checks checkov -f main.tf --check CKV_AWS_53,CKV_AWS_54

# Specify a custom policy directory checkov -f main.tf --external-checks-dir /path/to/custom/checks

Custom Policies and Rules

# Create and use custom policies checkov -f main.tf --external-checks-git https://github.com/your-org/custom-policies.git

# Use a specific branch for custom policies checkov -f main.tf --external-checks-git https://github.com/your-org/custom-policies.git --branch dev

Output Formats

# Generate JSON output checkov -f main.tf --output json

# Generate JUnit XML for CI integration checkov -f main.tf --output junitxml

# Save results to a file checkov -f main.tf --output json > results.json

# Generate SARIF format (for GitHub code scanning) checkov -f main.tf --output sarif

Set Blocking Level

# Soft-fail (return code 0 even with failures) checkov -f main.tf --soft-fail

Advanced Scanning

# Scan a Terraform plan file terraform plan -out=tfplan.binary terraform show -json tfplan.binary > tfplan.json checkov -f tfplan.json

# Scan for secrets in your code checkov -f main.tf --framework secrets

# Scan with multiple frameworks at once checkov -d . --framework terraform,secrets,dockerfile

# Scan specific variables checkov -f main.tf --var-file prod.tfvars

Integration with Platforms

# Integrate with Bridgecrew platform checkov -f main.tf --bc-api-key <your_api_key>

Creating a Custom Policy

Checkov supports custom policies in YAML format through its Policy-as-Code (PaC) framework, with a simplified YAML syntax. Custom policies require a metadata section to identify the general information about the policy and a definition section which defines the actual rules.

Here's a very basic custom policy that checks if an AWS S3 bucket has server-side encryption enabled:

metadata:   id: "CUSTOM_AWS_001"   name: "Ensure S3 buckets have encryption enabled"   category: "encryption"   severity: "MEDIUM"

definition:   and:     - resource_types:         - aws_s3_bucket       attribute: "server_side_encryption_configuration"       operator: "exists"

Save this as s3_encryption_policy.yaml in a directory structure like:

custom_policies/

└── yaml/

    └── s3_encryption_policy.yaml

Then run the following command with your custom policy:

checkov -f main.tf --external-checks-dir custom_policies

Scalr Integration with Checkov

Scalr has a native integration with Checkov that automatically scans the Terraform or OpenTofu code before the Terraform plan runs. To use Checkov in Scalr, enable the integration, pick the version, and pass any custom parameters you need.

Enabling the Checkov integration in Scalr with version and parameter settings

Once enabled, Checkov can then be enforced on all Scalr environments or select environments. Once enforced on environments, all runs within the environment will be forced to go through a Checkov scan before the Terraform plan executes:

Checkov scan enforced on Scalr environment before Terraform plan executes

If the Checkov scan is in hard failure mode, the Terraform run will automatically stop before the plan can execute. 

Optionally, custom parameters can be passed to determine Checkov's behavior in Scalr. For example, the “--soft-fail” parameter can be passed to return a code of 0, which will allow the run to continue.

Other options like skip-check or –external-checks can also be used as a custom parameter.

See all available parameters here.

Customization

Scalr supports importing and enforcing custom Checkov policies from external repositories. Users can specify a VCS provider, repository, branch, and folder containing their custom Checkov checks, which will be evaluated as part of the policy enforcement in designated environments.

  • Custom Policy Enforcement: Users can define and enforce security and compliance rules beyond Checkov's built-in policies.
  • VCS Integration: Import policies from GitHub, GitLab, Bitbucket, or other supported VCS providers.
  • Granular Control: Specify the repository, branch, and folder for Checkov policies.
  • Automatic Policy Evaluation: Checkov will run the external policies as part of the Terraform plan and apply process.

Scalr custom Checkov policy configuration with VCS repository settings

Testing

Anyone who has used Checkov knows that jumping from one version to another can take planning. Scalr lets you run multiple versions of Checkov on a single environment so you can stage the upgrade. Keep your current version on its strict setting and add the new version in soft-fail mode, so anything the newer version flags won't block runs yet. That gives your team time to look at whatever the new version finds in their Terraform code and fix it before the upgrade is enforced.

Where to start with Checkov

Checkov catches Terraform misconfigurations automatically before they reach production, when a fix is a quick code change instead of a production incident. Running it on every change also keeps your configurations consistent with frameworks like CIS, HIPAA, and SOC2.

If you want the quickest path, the Scalr integration runs Checkov during development without any CI/CD wiring on your side.

This blog has been verified for Terraform and OpenTofu

About the author
Ryan Feedirector of platform engineering at Scalr
Ryan Fee is the director of platform engineering at Scalr, with over 15 years of experience improving infrastructure experiences at companies large and small.