DEV Community

Securing Your Terraform Infrastructure with Checkov and GitHub Actions

Infrastructure as Code (IaC) has revolutionized how we provision and manage cloud resources. Tools like Terraform, Pulumi, and OpenTofu allow us to define infrastructure using code, making it versionable, repeatable, and scalable. However, with great power comes great responsibility. Misconfigurations in IaC can lead to massive security breaches, such as publicly exposed data storage or overly permissive access roles.

This is where Static Application Security Testing (SAST) comes in. SAST tools analyze your source code to find security vulnerabilities before the code is deployed. In this article, we'll explore how to apply SAST to a Terraform project using Checkov, a popular open-source static analysis tool for IaC, and how to automate this process using GitHub Actions.

(Note: We are intentionally avoiding tfsec for this demonstration to explore other powerful alternatives).

Why Checkov?

Checkov, created by Bridgecrew (now part of Prisma Cloud), is a static code analysis tool for IaC. It scans cloud infrastructure provisioned using Terraform, Terraform plan, Cloudformation, Kubernetes, Dockerfile, Serverless, or ARM Templates and detects security and compliance misconfigurations. It includes hundreds of built-in policies covering security and compliance best practices for AWS, Azure, and Google Cloud.

The Demo Scenario: A Vulnerable S3 Bucket

Let's start by creating a simple Terraform configuration for an AWS S3 bucket. We will intentionally introduce a security misconfiguration: making the bucket public without encryption.

Create a file named main.tf:

# main.tf
provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "my_vulnerable_bucket" {
  bucket = "my-company-public-data-bucket-12345"
}

# Misconfiguration 1: Public Read Access
resource "aws_s3_bucket_acl" "example" {
  bucket = aws_s3_bucket.my_vulnerable_bucket.id
  acl    = "public-read"
}
Enter fullscreen mode Exit fullscreen mode

If we were to deploy this, anyone on the internet could read the contents of this bucket. Let's see how Checkov can catch this before it reaches production.

Running Checkov Locally

You can easily install Checkov using Python's package manager, pip:

pip install checkov
Enter fullscreen mode Exit fullscreen mode

Once installed, navigate to the directory containing your main.tf and run:

checkov -d .
Enter fullscreen mode Exit fullscreen mode

The Output

Checkov will scan the directory and output a detailed report. You will see something like this:

       _               _              
   ___| |__   ___  ___| | _______   __
  / __| '_ \ / _ \/ __| |/ / _ \ \ / /
 | (__| | | |  __/ (__|   < (_) \ V / 
  \___|_| |_|\___|\___|_|\_\___/ \_/  

By Prisma Cloud | version: 3.1.0

terraform scan results:

Passed checks: 0, Failed checks: 3, Skipped checks: 0

Failed checks:
1. Check: CKV_AWS_20: "S3 Bucket has an ACL defined which allows public READ access."
        FAILED for resource: aws_s3_bucket_acl.example
        File: /main.tf:10-13
        Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/s3-1-acl-read-access

2. Check: CKV_AWS_19: "Ensure all data stored in the S3 bucket is securely encrypted at rest"
        FAILED for resource: aws_s3_bucket.my_vulnerable_bucket
        File: /main.tf:6-8

3. Check: CKV_AWS_21: "Ensure all data stored in the S3 bucket have versioning enabled"
        FAILED for resource: aws_s3_bucket.my_vulnerable_bucket
        File: /main.tf:6-8
Enter fullscreen mode Exit fullscreen mode

Checkov successfully identified our public ACL misconfiguration (CKV_AWS_20) and also pointed out that we are missing encryption at rest and versioning!

Automating SAST with GitHub Actions

Running SAST tools locally is great, but to truly secure your pipeline, you must automate it. We can use GitHub Actions to run Checkov on every Pull Request. This ensures no vulnerable code can be merged into the main branch.

Create a .github/workflows/checkov.yml file in your repository:

name: Checkov IaC Scan

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Run Checkov action
        uses: bridgecrewio/checkov-action@master
        with:
          directory: .
          framework: terraform
          output_format: cli
          soft_fail: false # Set to true if you don't want the build to fail on violations
Enter fullscreen mode Exit fullscreen mode

How it works:

  1. Trigger: The workflow runs on any push or pull request to the main branch.
  2. Checkout: It checks out your repository code.
  3. Checkov Action: It uses the official bridgecrewio/checkov-action to scan the current directory (.) specifically looking for Terraform files.
  4. Soft Fail: By setting soft_fail: false, the GitHub Action will fail if any vulnerabilities are found, blocking the Pull Request from being merged.

Fixing the Code

To fix our pipeline, we need to address the vulnerabilities in main.tf. Here is the secure version:

# main.tf
provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "my_secure_bucket" {
  bucket = "my-company-secure-data-bucket-12345"
}

# Fix 1: Private ACL
resource "aws_s3_bucket_acl" "example" {
  bucket = aws_s3_bucket.my_secure_bucket.id
  acl    = "private"
}

# Fix 2: Enable Versioning
resource "aws_s3_bucket_versioning" "versioning_example" {
  bucket = aws_s3_bucket.my_secure_bucket.id
  versioning_configuration {
    status = "Enabled"
  }
}

# Fix 3: Enable Server-Side Encryption
resource "aws_s3_bucket_server_side_encryption_configuration" "example" {
  bucket = aws_s3_bucket.my_secure_bucket.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Now, if you commit these changes, the GitHub Action will run Checkov again, and it will pass successfully!

Conclusion

Securing Infrastructure as Code is not optional; it is a critical part of modern cloud architecture. By integrating a SAST tool like Checkov into your GitHub Actions pipeline, you establish a strong first line of defense against misconfigurations. It shifts security "left," empowering developers to fix issues before they ever see the light of a production environment.

Demo Repository: You can find the complete code for this demo in my GitHub Repository: https://github.com/Cristhian465/Research-Team-Work-N-02-Sast-tools-for-infraestructure


If you found this article helpful, please leave a like or comment below! Have you used Checkov or other SAST tools? Share your experience!

Top comments (0)