Portfolio Project

Building a Terraform IaC
Security Scanner

A beginner's journey from zero Terraform knowledge to a fully automated DevSecOps pipeline — detecting cloud misconfigurations before they reach production.

Terraform Checkov GitHub Actions Ubuntu Linux DevSecOps AWS S3

Introduction

When I started this project, I had never written a single line of Terraform. What you're reading is the story of how I went from that starting point to building a fully automated cloud infrastructure security scanner — and what I learned along the way.

This project is part of my portfolio for Cloud Security Engineer roles. The goal was to demonstrate real-world DevSecOps skills: detecting misconfigurations in Infrastructure-as-Code (IaC) before they ever reach production.

💡

Companies deploy cloud infrastructure using Terraform every day. Misconfigurations — public S3 buckets, open firewall rules, missing encryption — are responsible for some of the biggest cloud data breaches in history. This project shows how to catch those problems automatically.

🛠 Tools & Technologies

Tool Category What It Does
Terraform Infrastructure-as-Code Defines cloud resources (S3, security groups, etc.) in code
Checkov IaC Security Scanner Analyzes Terraform files for security misconfigurations
GitHub Actions CI/CD Automation Automatically runs security scans on every code push
Ubuntu Linux Environment Development platform used throughout this project

Everything in this project is completely free. No cloud account, no credit card, and no deployed infrastructure required.

📁 Project Structure

Before writing any code, I set up the repository folder structure.

terraform-security-pipeline/
│
├── vulnerable-terraform/
│   └── main.tf          # intentionally insecure infrastructure
│
├── secure-terraform/
│   └── main.tf          # remediated, secure infrastructure
│
├── scan-reports/
│   ├── vulnerable-report.json
│   └── secure-report.json
│
├── .github/
│   └── workflows/
│       └── checkov-scan.yml  # CI/CD security pipeline
└── README.md

📦 Installation & Setup

Terraform was installed from the official HashiCorp website. Checkov required a workaround on Ubuntu 24 with Python 3.12.

📌

Documenting this PATH troubleshooting is intentional — it shows independent problem-solving, a core skill for any engineering role.

💥 Step 1 — Vulnerable Infrastructure

The first Terraform file contains intentional misconfigurations that represent real-world cloud security mistakes responsible for actual data breaches.

# ❌ INSECURE: Public S3 bucket with no protections
provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "bad_bucket" {
  bucket = "my-insecure-demo-bucket-12345"
}

resource "aws_s3_bucket_public_access_block" "bad_access" {
  bucket = aws_s3_bucket.bad_bucket.id

  block_public_acls       = false  # ❌ Public ACLs allowed
  block_public_policy     = false  # ❌ Public policies allowed
  ignore_public_acls      = false  # ❌ Public ACLs not ignored
  restrict_public_buckets = false  # ❌ Bucket publicly accessible
}

# ❌ INSECURE: SSH open to the entire internet
resource "aws_security_group" "bad_sg" {
  name = "bad-security-group"

  ingress {
    description = "SSH open to world"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]  # ❌ Anyone can SSH in
  }
}

⚠️ Why These Are Dangerous

Misconfiguration Real-World Risk
Public S3 bucket Sensitive data exposed to anyone on the internet — the leading cause of cloud data breaches
No encryption at rest Data stored unencrypted; if accessed, it is immediately readable
SSH open to 0.0.0.0/0 Any attacker can attempt to brute-force or exploit SSH on your server
No access logging No audit trail — unauthorized access cannot be detected or investigated
No versioning Ransomware or accidental deletion cannot be reversed

🔍 Step 2 — Running the First Security Scan

checkov -d vulnerable-terraform
# Save results as JSON for the portfolio
checkov -d vulnerable-terraform -o json > scan-reports/vulnerable-report.json

The scan caught real misconfigurations immediately. Summary: 9 Passed / 14 Failed

🔎

Every single finding maps to a real attack scenario. Checkov links to documentation explaining exactly why each configuration is dangerous.

🔒 Step 3 — Remediating the Infrastructure

The secure version fixes all critical issues: public access is fully blocked, encryption is enabled, versioning is on, and SSH is restricted to a private CIDR range.

# ✅ SECURE: S3 bucket with full protections
resource "aws_s3_bucket" "secure_bucket" {
  bucket = "my-secure-demo-bucket-67890"
}

# ✅ Block all public access
resource "aws_s3_bucket_public_access_block" "secure_access" {
  bucket                  = aws_s3_bucket.secure_bucket.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# ✅ Enable versioning
resource "aws_s3_bucket_versioning" "versioning" {
  bucket = aws_s3_bucket.secure_bucket.id
  versioning_configuration { status = "Enabled" }
}

# ✅ Enable AES-256 encryption at rest
resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" {
  bucket = aws_s3_bucket.secure_bucket.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

# ✅ SSH restricted to private network only
resource "aws_security_group" "secure_sg" {
  name = "secure-security-group"
  ingress {
    description = "Restricted SSH"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/16"]  # ✅ Internal network only
  }
}

📊 Step 4 — Scan Comparison: Before vs After

checkov -d secure-terraform
checkov -d secure-terraform -o json > scan-reports/secure-report.json

Before Remediation

9
Passed
14
Failed

After Remediation

16
Passed
7
Failed

The remaining failures are advanced configurations (KMS encryption, cross-region replication) appropriate for production but outside the scope of this demonstration lab. All critical public exposure and SSH vulnerabilities were fully remediated.

⚙️ Step 5 — Automating with GitHub Actions

Every push to the repository automatically triggers Checkov. If new misconfigurations are introduced, the pipeline flags them before they reach production.

name: Terraform Security Scan

on:
  push:
  pull_request:

jobs:
  checkov-scan:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    - name: Run Checkov
      uses: bridgecrewio/checkov-action@master
      with:
        directory: .
Developer Push GitHub Actions Checkov Scan Security Report

🧠 What I Learned

Technical Skills

Security Knowledge

🚀 What's Next


📁  github.com/MarcoAbreu2002/terraform-security-pipeline