In my experience, the most expensive security bugs aren’t the ones found in the application code—they’re the ones found in the infrastructure. A single misconfigured S3 bucket or an open SSH port in a security group can negate an entire year of security patching. That’s why I’ve shifted my focus toward automating IaC security with Checkov.
Checkov is a static code analysis tool for Infrastructure as Code. It allows you to scan your Terraform, Kubernetes, Helm, and CloudFormation files against hundreds of predefined policies to ensure you aren’t deploying a security hole. By implementing this early, you’re effectively ‘shifting left,’ catching vulnerabilities before the terraform apply command even touches your cloud provider.
If you’re already looking at securing your runtime environment, you might find my guide on zero trust architecture for cloud infrastructure a great companion to this tutorial.
Prerequisites
Before we dive into the automation, ensure you have the following installed on your local machine:
- Python 3.7+ (Checkov is Python-based)
- Pip (Python package manager)
- A sample IaC project (Terraform or Kubernetes manifests)
- A GitHub account for the CI/CD portion of this guide
Step 1: Installing Checkov Locally
I always recommend starting locally to understand the output before moving to a pipeline. Installing Checkov is straightforward via pip.
pip install checkov
Once installed, you can verify it’s working by running:
checkov --version
Step 2: Running Your First Scan
Navigate to the root of your infrastructure folder. For this example, I’m using a Terraform project with a few AWS resources. Run the following command to scan the current directory:
checkov -d .
Checkov will recursively scan all files. You’ll see a detailed report in your terminal. Failed checks are highlighted in red, while passed checks are green. As shown in the image below, the output provides the exact line number and the CKV ID (e.g., CKV_AWS_20) which links to the official documentation on how to fix the issue.
Step 3: Handling False Positives (Suppression)
In a real-world production environment, not every ‘failed’ check is a critical risk. Sometimes, a business requirement forces a specific configuration. I don’t like ignoring warnings blindly, but Checkov allows for targeted suppression.
To skip a specific check for a resource, add a comment directly above the resource block in your Terraform code:
# checkov:skip=CKV_AWS_20: "S3 bucket must have public access block; this bucket is intentionally public for static website hosting"
resource "aws_s3_bucket" "public_assets" {
bucket = "my-public-assets-bucket"
}
Step 4: Automating Security with GitHub Actions
Running scans manually is a recipe for human error. To truly succeed in automating IaC security with Checkov, you need to integrate it into your PR process. Here is the YAML configuration I use for my GitHub Actions pipeline.
name: IaC Security Scan
on: [pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: .
framework: terraform # You can add kubernetes, cloudformation, etc.
soft_fail: false # This will fail the build if a security gap is found
By setting soft_fail: false, I ensure that no code enters the main branch unless it passes our security baseline. This creates a mandatory quality gate for the team.
Pro Tips for Scalability
- Custom Policies: If your company has specific compliance needs (like HIPAA or PCI), you can write your own policies using Python or YAML.
- JSON Output: Use
checkov -d . --output json > results.jsonif you want to feed the results into a security dashboard or a custom reporting tool. - Combine with Container Scans: IaC security is only half the battle. I recommend pairing this with a step-by-step Trivy container scanning guide to ensure both your infrastructure and your images are secure.
Troubleshooting Common Issues
Issue: “Checkov not found” after installation.
This usually happens because the Python script directory isn’t in your system PATH. Try running python3 -m checkov -d . instead, or add ~/.local/bin to your PATH.
Issue: Too many failures on a legacy project.
If you’re introducing Checkov to a massive existing codebase, don’t fail the build immediately. Start with soft_fail: true and create a backlog of security tickets to fix the most critical issues first.
What’s Next?
Now that you’ve automated your scanning, the next step is to move toward a more comprehensive security posture. I suggest looking into automated remediation or exploring how to integrate these checks into a larger DevSecOps lifecycle. If you’re feeling overwhelmed by the number of tools, remember that consistency is better than perfection—start with one tool (like Checkov) and expand from there.