Tutorials
Tutorials
March 7, 2025

Using Checkov with Terraform - Integrations, Features, Examples

By
Ryan Fee

What is Checkov

Checkov is an open-source static code analysis tool designed for infrastructure-as-code (IaC) security. Developed by Bridgecrew (acquired by Palo Alto Networks), it scans cloud infrastructure configurations written in Terraform, CloudFormation, Kubernetes, Dockerfile, and ARM templates to identify misconfigurations and security vulnerabilities before deployment. Checkov uses predefined policies to detect common security issues such as unencrypted storage, excessive permissions, open security groups, and publicly exposed resources. The tool integrates easily into CI/CD pipelines, offers customizable policies, and provides detailed reports with remediation guidance, making it valuable for organizations implementing DevSecOps practices by shifting security left in the development process.

In this blog, we’ll primarily focus on the integration with Terraform and OpenTofu. Scalr has a native integration with Checkov, which is reviewed at the bottom of this blog.

Why is Checkov Needed?

Checkov is crucial because it addresses a critical vulnerability in infrastructure as code: Terraform code misconfigurations. As organizations adopt infrastructure as code practices, security gaps will emerge not from sophisticated attacks but from simple misconfigured resources like unencrypted databases, overly permissive IAM roles, or exposed storage buckets. By automatically scanning configuration files early in the development process, Checkov prevents these vulnerabilities from reaching production environments, which could lead to data breaches or compliance violations. This "shift-left" approach to security integrates seamlessly into existing Terraform development workflows, reduces remediation costs by catching issues early, and helps organizations maintain compliance with industry standards like CIS, HIPAA, and SOC2. Checkov's ability to continuously validate infrastructure against security best practices becomes essential for maintaining a strong security posture.

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 can be found here.

To understand the basics of Checkov, let’s create a simple Terraform module that we know has some security vulnerabilities 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 and techniques for more sophisticated scanning and customization for 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 which will automatically execute the scanning of the Terraform or OpenTofu code prior to the Terraform plan running. To use Checkov in Scalr, you simply enable the integration, select the version, and then provide any custom parameters that need to be set.

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:

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.

Testing

If you are familiar with Checkov, you know that upgrading from one version to another can require planning. Scalr allows you to run multiple versions of Checkov on a single environment to help you plan the upgrade. Your existing version might have a strict setting, while the new version has a soft fail, which means that anything failing in the newer version will not block runs. Users now have time to understand any vulnerabilities their Terraform code might have and update it accordingly.

Summary

Terraform code misconfigurations are among the leading causes of cloud security breaches, making Checkov essential because it automatically detects these vulnerabilities before they reach production environments. By integrating Checkov into your DevOps workflow, you cannot only prevent costly security incidents but also educate your team on best practices, creating a continuously improving security culture across your organization.

The Scalr integration makes it easy to get started with Checkov. It implements proper "shift-left" security that identifies these vulnerabilities during development rather than after deployment when remediation is costlier and more disruptive.

Note: While this blog references Terraform, everything mentioned in here also applies to OpenTofu. New to OpenTofu? It is a fork of Terraform 1.5.7 as a result of the license change from MPL to BUSL by HashiCorp. OpenTofu is an open-source alternative to Terraform that is governed by the Linux Foundation. All features available in Terraform 1.5.7 or earlier are also available in OpenTofu. Find out the history of OpenTofu here.

Your costs = usage. Period.

A screenshot of the modules page in the Scalr Platform