⭐ Why I Built This Project
(Project 6 of 6 — Terraform Security Module: Secure AWS Baseline with Infrastructure as Code)
Instead of studying cloud security concepts in isolation, I’m using real job descriptions as a roadmap and building hands-on projects that map directly to cloud security, cloud operations, and security engineering roles.
This 6-part series focuses on practical, cloud security skills, including:
- Identity hardening and MFA enforcement
- IAM governance and access reviews
- Continuous monitoring of cloud resources
- Misconfiguration detection and drift analysis
- Log analysis, audit readiness, and evidence gathering
- Infrastructure-as-Code (IaC) security baselines and guardrails
- Guard rails at scale using AWS Organizations + Service Control Policies (SCPs)
- Threat detection, anomaly monitoring, and incident triage
Each project is designed to reflect real-world responsibilities, not just theoretical learning.
📌 Project Sequence
👉 Part 1: AWS IAM Hardening — strengthening identity boundaries and improving authentication hygiene
👉 Part 2: Cloud Security Posture Management (CSPM) using Security Hub + AWS Config
👉 Part 3: CASB-Like Monitoring with GuardDuty + CloudTrail, focusing on anomalies, delegated admin, and safe threat simulation
👉 Part 4: Drift Detection with AWS Config, using managed rules, EventBridge routing, tags, and optional remediation
👉 Part 5: Log Analysis & Dashboards with Athena + QuickSight, turning raw CloudTrail logs into actionable security insights
👉 Part 6: (this project) — Terraform Security Module, building a secure AWS baseline using Infrastructure as Code
🧱 Why This Project Matters
In real-world cloud environments, security doesn’t start in the console, it starts in code.
Modern cloud security teams rely on Infrastructure as Code (IaC) tools like Terraform to ensure environments are:
- Secure by default
- Consistent across deployments
- Auditable and reviewable
- Resistant to configuration drift
This project focuses on using Terraform to define and deploy a secure AWS foundation, including:
- A baseline VPC configuration
- A secure S3 bucket with encryption, versioning, and public access blocked
- CloudTrail logging enforced through code
Instead of manually clicking through the AWS console, this project demonstrates how security controls can be:
- Version-controlled
- Peer-reviewed
- Re-deployed on demand
- Automatically restored if misconfigured
You’ll also see how Terraform helps detect and prevent drift, a critical requirement in regulated and enterprise cloud environments.
To keep the project accessible and low-cost, Terraform is executed using AWS CloudShell, eliminating local installation challenges (especially on Windows ARM systems) while still following real-world DevSecOps workflows.
By the end of this project, you’ll have a repeatable, secure AWS baseline defined entirely in code, a strong capstone that ties together identity, monitoring, logging, and governance concepts from the entire series and aligns directly with expectations for cloud security and cloud operations roles.
Beginner-Friendly | Fun | Technical | Real-World Cloud Security Project
Welcome to Project 6 - Terraform Security Module, where you’ll learn how to build a secure AWS baseline using Terraform, AWS CloudShell, and a workflow that mirrors real cloud security engineering.
This guide is fun, practical, and perfect for beginners who want hands-on cloud security experience without breaking the bank.
📚 Table of Contents
- Introduction
- Why This Project Matters
- Prerequisites
- Using VS Code vs CloudShell
- Setting Up AWS CloudShell
- Creating Your Terraform Project Structure
- Writing Terraform Configuration Files
- Initializing Terraform
- Planning and Applying
- Verifying the Deployment
- Cleaning Up Resources
- Troubleshooting Tips
- Final Thoughts
🌟 Introduction
Terraform is one of the most powerful Infrastructure-as-Code (IaC) tools in the cloud ecosystem.
But installing Terraform locally, especially on Windows ARM devices, can get complicated.
So instead, we take the fun, beginner-friendly, zero-hassle route:
🎉 Run Terraform directly inside AWS CloudShell, which comes preconfigured with AWS credentials and a Linux environment, exactly like real DevOps teams use.
🔐 Why This Project Matters
You will create three essential security components using Terraform:
- A VPC (Virtual Private Cloud)
- A Secure S3 Bucket for CloudTrail logs
- A CloudTrail Trail for auditing AWS activity
These are foundational in cloud security operations, compliance, and threat detection.
This entire environment is:
✔ Free or extremely low-cost
✔ Fully repeatable using IaC
✔ Destroyable in minutes
✔ Perfect for portfolios
🧰 Prerequisites
- AWS account
- Basic familiarity with AWS Console
- A browser (for CloudShell)
- Optional: VS Code for code editing
No Terraform account required.
No installations on your laptop required.
💻 Using VS Code vs AWS CloudShell
You can write Terraform locally in VS Code, but ARM64 Windows devices don’t have native Terraform binaries.
So the recommended approach is:
🥇 Use VS Code for editing
🥇 Use AWS CloudShell for running Terraform
CloudShell gives you:
- Linux environment
- Pre-installed Terraform (or installable)
- Preconfigured IAM authentication
- Safe sandbox
This combo gives you real-world DevSecOps workflow.
☁️ Setting Up AWS CloudShell
- Log in to the AWS Console
- Click the CloudShell terminal icon in the upper-right corner
- CloudShell opens a terminal inside AWS
- Check if Terraform is installed:
terraform version
If Terraform is missing:
- Run
uname -mto detect architecture - Install Terraform using the latest ARM64 or AMD64 Linux binary
sudo yum install -y wget unzip
TERRAFORM_VERSION="1.14.2"
//At the time of this project **1.14.2** was the most recent version of terraform.
wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip
unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip
sudo mv terraform /usr/local/bin/
terraform version
📁 Creating Your Terraform Project Structure
Inside CloudShell:
mkdir terraform-security-module
cd terraform-security-module
Recommended real-world folder structure:
terraform-security-module/
│
├── main.tf
├── variables.tf
├── outputs.tf
├── versions.tf
└── .gitignore
Add a .gitignore:
.terraform/
terraform.tfstate
terraform.tfstate.backup
*.backup
🛠 Writing Terraform Configuration Files
Below is the full configuration needed to deploy a secure AWS baseline.
🔹 versions.tf
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
🔹 variables.tf
variable "aws_region" {
description = "AWS region to deploy into"
type = string
default = "us-east-1"
}
variable "project_name" {
description = "Prefix for all resource names"
type = string
default = "tf-security-demo"
}
🔹 main.tf
Contains:
- VPC
- S3 bucket
- Public access block
- Versioning
- Encryption
- Bucket policy
- CloudTrail
Note: I added notes to describe what each section should complete.
//Create a basic VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.project_name}-vpc"
Environment = "lab"
ManagedBy = "terraform"
}
}
//Generate Unique Suffix to Avoid Bucket Name Conflicts
resource "random_id" "suffix" {
byte_length = 4
}
//Create the Bucket
resource "aws_s3_bucket" "cloudtrail_logs" {
bucket = "${var.project_name}-cloudtrail-logs-${random_id.suffix.hex}"
tags = {
Name = "${var.project_name}-cloudtrail-logs"
Environment = "lab"
ManagedBy = "terraform"
}
}
//Block All Public Access
resource "aws_s3_bucket_public_access_block" "cloudtrail_logs" {
bucket = aws_s3_bucket.cloudtrail_logs.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
//Enable Versioning
resource "aws_s3_bucket_versioning" "cloudtrail_logs" {
bucket = aws_s3_bucket.cloudtrail_logs.id
versioning_configuration {
status = "Enabled"
}
}
//Enable Encryption (SSE-S3)
resource "aws_s3_bucket_server_side_encryption_configuration" "cloudtrail_logs" {
bucket = aws_s3_bucket.cloudtrail_logs.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
//Bucket Policy for CloudTrail
data "aws_caller_identity" "current" {}
resource "aws_s3_bucket_policy" "cloudtrail_logs" {
bucket = aws_s3_bucket.cloudtrail_logs.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AWSCloudTrailAclCheck"
Effect = "Allow"
Principal = {
Service = "cloudtrail.amazonaws.com"
}
Action = "s3:GetBucketAcl"
Resource = aws_s3_bucket.cloudtrail_logs.arn
},
{
Sid = "AWSCloudTrailWrite"
Effect = "Allow"
Principal = {
Service = "cloudtrail.amazonaws.com"
}
Action = "s3:PutObject"
Resource = "${aws_s3_bucket.cloudtrail_logs.arn}/AWSLogs/${data.aws_caller_identity.current.account_id}/*"
Condition = {
StringEquals = {
"s3:x-amz-acl" = "bucket-owner-full-control"
}
}
}
]
})
}
//Create a CloudTrail Trail
resource "aws_cloudtrail" "main" {
name = "${var.project_name}-trail"
s3_bucket_name = aws_s3_bucket.cloudtrail_logs.id
include_global_service_events = true
is_multi_region_trail = true
enable_logging = true
event_selector {
read_write_type = "All"
include_management_events = true
}
depends_on = [
aws_s3_bucket_policy.cloudtrail_logs,
aws_s3_bucket_public_access_block.cloudtrail_logs
]
tags = {
Name = "${var.project_name}-trail"
Environment = "lab"
ManagedBy = "terraform"
}
}
🔹 outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
}
output "cloudtrail_logs_bucket" {
value = aws_s3_bucket.cloudtrail_logs.bucket
}
output "cloudtrail_trail_name" {
value = aws_cloudtrail.main.name
}
output "region" {
value = var.aws_region
}
⚙️ Initializing Terraform in CloudShell
Run:
terraform init
terraform validate
Your environment is now ready.
🚀 Planning and Applying
Preview what Terraform will create:
terraform plan -out tfplan
Apply the infrastructure:
terraform apply tfplan
Terraform will deploy:
- A new secure VPC
- A CloudTrail-ready S3 bucket
- Encryption + versioning + public access blocks
- A CloudTrail trail
🔍 Verifying the Deployment
Check VPC
AWS Console → VPC → Your VPCs → Look for the name tf-security-demo-vpc
Check S3
Look for:
✔ Versioning enabled
✔ AES-256 encryption
✔ Public Access Block = ON
Check CloudTrail
AWS Console → CloudTrail → Trails → Your trail should be active
🧹 Cleaning Up Resources
Always run this to avoid costs:
terraform destroy
Confirm with yes when prompted.
CloudShell removes:
- CloudTrail
- S3 bucket
- VPC
🛠 Troubleshooting Tips
❗ Terraform not found
Install Terraform manually inside CloudShell after running:
uname -m
❗ Permission denied
Ensure your IAM user has:
- S3 bucket creation permissions
- CloudTrail permissions
- VPC permissions
❗ S3 bucket name already exists
Use random suffix:
resource "random_id" "suffix" {
byte_length = 4
}
🎉 Final Thoughts
You just built:
- A secure AWS logging architecture
- Using Terraform
- Inside AWS CloudShell
- Without installing anything locally
This is professional-grade IaC experience—perfect for:
- Cloud Security
- DevOps
- SOC roles
- Portfolio projects

