14 / 75 · 08 Infrastructure as Code Testing · Policy as Code← prev⊞ allnext →☰ Read as one page
3.4Checkov: Batteries Included
Checkov ships with 1000+ built-in rules and requires zero configuration to start catching issues. It is particularly strong for teams that want immediate value without writing custom policies.
Quick Start
# Scan a Terraform directory
checkov -d ./terraform/ --framework terraform
# Output example:
# Passed checks: 42, Failed checks: 3, Skipped: 0
#
# Check: CKV_AWS_18: "Ensure the S3 bucket has access logging enabled"
# FAILED for resource: aws_s3_bucket.data
# File: /main.tf:15-22
#
# Check: CKV_AWS_145: "Ensure S3 bucket is encrypted with KMS"
# FAILED for resource: aws_s3_bucket.data
# File: /main.tf:15-22
# Run only specific checks
checkov -d ./terraform/ --check CKV_AWS_18,CKV_AWS_145
# Skip specific checks (with justification)
checkov -d ./terraform/ --skip-check CKV_AWS_18 \
--skip-check-reason "Access logging handled by CloudTrail"
# Output as JSON for CI parsing
checkov -d ./terraform/ --output json > checkov-results.json
# Scan multiple frameworks at once
checkov -d . --framework terraform,kubernetes,dockerfile
Custom Checkov Policies in Python
When built-in checks are not enough, write custom policies in Python:
# custom_checks/s3_naming_convention.py
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories
class S3NamingConvention(BaseResourceCheck):
"""Ensure S3 bucket names follow organizational naming convention."""
def __init__(self):
name = "Ensure S3 bucket follows naming convention: {team}-{env}-{purpose}"
id = "CUSTOM_S3_001"
supported_resources = ["aws_s3_bucket"]
categories = [CheckCategories.CONVENTION]
super().__init__(name=name, id=id, categories=categories,
supported_resources=supported_resources)
def scan_resource_conf(self, conf):
bucket_name = conf.get("bucket", [""])[0]
# Pattern: team-environment-purpose
parts = bucket_name.split("-")
if len(parts) < 3:
return CheckResult.FAILED
valid_envs = ["dev", "staging", "prod", "test"]
if parts[1] not in valid_envs:
return CheckResult.FAILED
return CheckResult.PASSED
check = S3NamingConvention()
Pre-Commit Integration
# .pre-commit-config.yaml
repos:
- repo: https://github.com/bridgecrewio/checkov
rev: '3.2.0'
hooks:
- id: checkov
args: ['--compact', '--framework', 'terraform']