Your costs = usage. Period.

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.
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.
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:
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.
Here are some advanced Checkov commands and techniques for more sophisticated scanning and customization for Terraform and OpenTofu:
# 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
# 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
# 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
# Soft-fail (return code 0 even with failures)
checkov -f main.tf --soft-fail
# 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
# Integrate with Bridgecrew platform
checkov -f main.tf --bc-api-key <your_api_key>
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 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.
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.
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.
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.