DEV Community

Shantanu Sarode
Shantanu Sarode

Posted on

How to Secure Existing Terraform Code Using Checkov and GitHub Actions

Step 1: Writing the GitHub Actions Workflow

To automate our security scans, we need to tell GitHub how and when to run Checkov. We do this by creating a simple YAML configuration file.

In your Terraform repository, create a new file at this exact path: .github/workflows/checkov.yml.

Copy and paste the following standard template into that file:

name: DevSecOps - Checkov Scan

1. When should this pipeline run?

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
checkov-scan:
name: Run Checkov Security Scan
runs-on: ubuntu-latest

steps:
  # 2. Pull the Terraform code into the runner
  - name: Checkout Code
    uses: actions/checkout@v4

  # 3. Execute the Checkov scan against the directory
  - name: Run Checkov
    uses: bridgecrewio/checkov-action@master
    with:
      directory: . # Scans the root directory. Change this if your TF files are in a specific folder.
      framework: terraform 
      # soft_fail: true # Uncomment this line if you want the pipeline to pass even if vulnerabilities are found
Enter fullscreen mode Exit fullscreen mode

The Trigger (on:): This tells GitHub Actions to trigger the scan every time someone pushes code to the main branch or opens a Pull Request. This ensures no unreviewed code bypasses the security check.

The Runner (runs-on:): GitHub spins up a temporary, fresh Ubuntu Linux server to execute our scan.

The Action (uses: bridgecrewio/checkov-action): Instead of manually installing Python and Checkov on the runner, we use the official pre-built Checkov action. We specify the framework: terraform so it knows exactly what syntax to look for.

Step 2: Triggering the Pipeline and Reading the Logs

To see Checkov in action, let us introduce a deliberate security flaw. Imagine a team member adds a new AWS S3 bucket to your Terraform code but forgets to enable encryption.

resource "aws_s3_bucket" "my_company_data" {
bucket = "company-sensitive-data-bucket"
# Missing encryption configuration!
}

When this code is pushed to the repository, GitHub Actions automatically triggers our Checkov workflow. Because the bucket lacks encryption, Checkov will catch it, fail the pipeline step, and stop the deployment.

Check: CKV_AWS_19: "Ensure all data stored in the S3 bucket is securely encrypted at rest"
FAILED for resource: aws_s3_bucket.my_company_data
File: /main.tf:12-15
Guide: https://docs.bridgecrew.io/docs/s3_14-s3-bucket-encryption

            12 | resource "aws_s3_bucket" "my_company_data" {
            13 |   bucket = "company-sensitive-data-bucket"
            14 | }
Enter fullscreen mode Exit fullscreen mode

The Check ID (CKV_AWS_19): This is the specific security rule that failed. You can search this ID to understand the exact risk.

The File & Line Number (/main.tf:12-15): You do not have to hunt for the mistake. The console log tells you exactly which file and which lines of code need attention.

The Guide: Checkov provides a direct URL to its documentation explaining how to fix this exact vulnerability.

Step 3: Resolving the Vulnerability

Now that the pipeline has explicitly told us what is missing and where to find it, fixing the code is straightforward.

We navigate back to our /main.tf file and add the required server-side encryption block to our S3 bucket resource to satisfy the security requirement.

resource "aws_s3_bucket" "my_company_data" {
bucket = "company-sensitive-data-bucket"
}

Adding the required encryption configuration to resolve CKV_AWS_19

resource "aws_s3_bucket_server_side_encryption_configuration" "my_company_data_encryption" {
bucket = aws_s3_bucket.my_company_data.id

rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}

Once we commit and push this updated code, GitHub Actions triggers the Checkov workflow again. This time, Checkov scans the directory, verifies that the encryption configuration is present, and outputs a successful log. The pipeline turns green, and the code is now safe to merge and deploy.

Wrapping Up

Integrating tools like Checkov directly into your CI/CD pipeline shifts security left. Instead of relying on manual code reviews to catch missing encryption or overly permissive security groups, your pipeline does the heavy lifting. It prevents configuration drift, catches human errors early, and ensures that your existing Terraform infrastructure remains secure as it scales.

If you are setting this up in your own environment and run into any console errors, drop a comment below and I would be happy to help troubleshoot!

Top comments (0)