β 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
Top comments (0)