<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex Vancer</title>
    <description>The latest articles on DEV Community by Alex Vancer (@alex_vancer_0663dc3af45d4).</description>
    <link>https://dev.to/alex_vancer_0663dc3af45d4</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4235011%2F3b338b3b-21c3-4950-8084-83362c073d03.png</url>
      <title>DEV Community: Alex Vancer</title>
      <link>https://dev.to/alex_vancer_0663dc3af45d4</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alex_vancer_0663dc3af45d4"/>
    <language>en</language>
    <item>
      <title>How We Automated 80+ Hours of AWS Security Hardening into a Single Terraform Module</title>
      <dc:creator>Alex Vancer</dc:creator>
      <pubDate>Mon, 09 Nov 2026 11:46:59 +0000</pubDate>
      <link>https://dev.to/alex_vancer_0663dc3af45d4/how-we-automated-80-hours-of-aws-security-hardening-into-a-single-terraform-module-ac6</link>
      <guid>https://dev.to/alex_vancer_0663dc3af45d4/how-we-automated-80-hours-of-aws-security-hardening-into-a-single-terraform-module-ac6</guid>
      <description>&lt;p&gt;If you’ve ever prepared an AWS infrastructure for a SOC 2 Type II or GDPR compliance audit, you know the drill.&lt;/p&gt;

&lt;p&gt;What starts as a clean cloud architecture quickly devolves into 80+ hours of tedious manual hardening: stitching together KMS keys, locking down IAM boundary policies, configuring S3 block public access, routing CloudTrail log delivery, and ensuring zero 0.0.0.0/0 ingress rules in your VPC security groups.&lt;/p&gt;

&lt;p&gt;And the worst part? Manual hardening creates configuration drift. Two months after the audit, someone opens a temporary SSH port or forgets to encrypt an EBS volume, and your compliance posture crumbles.&lt;/p&gt;

&lt;p&gt;We got tired of re-inventing the same security wheel across every deployment. So we engineered a battle-tested approach to collapse those 80+ manual hours into a single, automated, production-ready IaC? baseline.&lt;/p&gt;

&lt;p&gt;Here is the exact framework we used, the architectural decisions behind it, and how you can automate security gating in your own CI/CD pipeline.&lt;br&gt;
The 5 Core Compliance Pillars Most AWS Setups Miss&lt;/p&gt;

&lt;p&gt;When auditing standard Terraform setups, we consistently find the same 5 critical security gaps that auditors flag instantly:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuyni2pqtw12zkpudnsnn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuyni2pqtw12zkpudnsnn.png" alt=" " width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Default VPC Left Intact&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Leaving the default AWS VPC enabled in any active region is an immediate audit penalty. Default VPCs have public subnets and internet gateways pre-configured, making it trivial for a developer to launch an exposed resource by accident.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Missing S3 Public Access Block at Account Level&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Encrypting an S3 bucket isn't enough if someone can override bucket policies. Security baselines require account-level S3 Public Access Block enforcement alongside mandatory Customer Managed Keys (CMK) via KMS.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Loose IAM Boundary Policies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Granting AdministratorAccess or loose wildcard * actions during early development usually bleeds into production. Baseline architectures require strict IAM Permission Boundaries that set maximum allowable permissions regardless of role policies.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Unencrypted CloudTrail Logs Without KMS&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Default CloudTrail logs use AWS-managed keys. Auditors require logs encrypted with dedicated KMS keys with key rotation enabled, paired with S3 bucket object-locking to prevent log tampering.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Ingress on Security Groups&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Security groups allowing ingress from 0.0.0.0/0 on management ports (22, 3389, 5432) are the #1 source of automated cloud exploits.&lt;br&gt;
Architectural Deep Dive: Automating Hardening in Terraform&lt;/p&gt;

&lt;p&gt;Instead of applying security rules piecemeal, we structured our baseline module to enforce security properties by default upon instantiation.&lt;/p&gt;

&lt;p&gt;Here is a simplified pattern showing how we enforce zero-trust S3 encryption and public access lockdown natively within our IaC baseline:&lt;/p&gt;

&lt;h1&gt;
  
  
  main.tf - Hardened S3 Bucket Pattern
&lt;/h1&gt;

&lt;p&gt;resource "aws_kms_key" "baseline_kms" {&lt;br&gt;
  description             = "Dedicated KMS key for S3 bucket encryption"&lt;br&gt;
  deletion_window_in_days = 30&lt;br&gt;
  enable_key_rotation     = true&lt;/p&gt;

&lt;p&gt;tags = {&lt;br&gt;
    Environment = var.environment&lt;br&gt;
    ManagedBy   = "Terraform"&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_s3_bucket" "audit_logs" {&lt;br&gt;
  bucket        = "${var.prefix}-${var.environment}-audit-logs"&lt;br&gt;
  force_destroy = false&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_s3_bucket_server_side_encryption_configuration" "audit_logs" {&lt;br&gt;
  bucket = aws_s3_bucket.audit_logs.id&lt;/p&gt;

&lt;p&gt;rule {&lt;br&gt;
    apply_server_side_encryption_by_default {&lt;br&gt;
      kms_master_key_id = aws_kms_key.baseline_kms.arn&lt;br&gt;
      sse_algorithm     = "aws:kms"&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_s3_bucket_public_access_block" "audit_logs" {&lt;br&gt;
  bucket = aws_s3_bucket.audit_logs.id&lt;/p&gt;

&lt;p&gt;block_public_acls       = true&lt;br&gt;
  block_public_policy     = true&lt;br&gt;
  ignore_public_acls      = true&lt;br&gt;
  restrict_public_buckets = true&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;By abstracting these compliance rules into reusable module defaults, developers cannot provision resources that violate organizational security policies.&lt;br&gt;
Shift-Left: Catching Security Drift in CI/CD&lt;/p&gt;

&lt;p&gt;Writing secure Terraform is only half the battle. You also need an automated gate in your CI/CD pipeline to reject pull requests that introduce compliance drift or insecure configurations.&lt;/p&gt;

&lt;p&gt;We built a lightweight static analysis runner that integrates directly into GitHub Actions to scan your IaC before any terraform apply touches production.&lt;br&gt;
Step-by-Step CI/CD Gating Workflow&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pull Request Trigger: Developer opens a PR modifying Terraform files.

Automated Static Analysis: CI runner evaluates HCL code against SOC 2 and GDPR control maps.

Inline PR Feedback: Violations (e.g., missing KMS key rotation or open security group rules) are flagged directly in the PR diff.

Merge Block: PR cannot be merged until all baseline violations are resolved.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;How to Check Your AWS IaC Baseline for Free&lt;/p&gt;

&lt;p&gt;If you want to test your current Terraform codebase against standard SOC 2 and GDPR security baselines without spending hours digging through AWS documentation, we open-sourced our checking tool.&lt;/p&gt;

&lt;p&gt;You can drop the Vancer Baseline Checker directly into your GitHub Actions workflow:&lt;/p&gt;

&lt;p&gt;name: "AWS Infrastructure Security Check"&lt;/p&gt;

&lt;p&gt;on:&lt;br&gt;
  pull_request:&lt;br&gt;
    branches: [ main ]&lt;/p&gt;

&lt;p&gt;jobs:&lt;br&gt;
  security-check:&lt;br&gt;
    runs-on: ubuntu-latest&lt;br&gt;
    steps:&lt;br&gt;
      - name: Checkout Code&lt;br&gt;
        uses: actions/checkout@v4&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - name: Run Vancer Baseline Checker
    uses: vancer-systems/baseline-checker-action@v1
    with:
      terraform_dir: './infrastructure'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It scans your HCL files and gives you instant visibility into security gaps before an auditor does.&lt;br&gt;
Wrapping Up&lt;/p&gt;

&lt;p&gt;Hardening AWS infrastructure doesn't have to consume weeks of high-value engineering time. By combining module-level defaults in Terraform/OpenTofu with automated CI/CD security gating, you turn compliance from a chaotic audit rush into a quiet, continuous background process.&lt;/p&gt;

&lt;p&gt;How is your team currently handling AWS IaC compliance? Do you manage hardening rules manually, or have you automated your security gating? Let's discuss in the comments below!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>cybersecurity</category>
      <category>terraform</category>
    </item>
  </channel>
</rss>
