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:

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.

Example of Checkov terminal output showing failed and passed security checks for Terraform
Example of Checkov terminal output showing failed and passed security checks for Terraform

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

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.