######################################## # Terraform Configuration ######################################## terraform { required_version = ">= 1.6.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } random = { source = "hashicorp/random" version = "~> 3.6" } } } ######################################## # Provider Configuration ######################################## provider "aws" { region = var.aws_region default_tags { tags = merge( { Project = var.project_name Environment = var.environment ManagedBy = "Terraform" CreatedBy = "Aether" }, var.additional_tags ) } } ######################################## # VPC ######################################## resource "aws_vpc" "main" { cidr_block = var.vpc_cidr enable_dns_support = true enable_dns_hostnames = true tags = { Name = "${var.project_name}-${var.environment}-vpc" } } ######################################## # Public Subnets ######################################## resource "aws_subnet" "public" { count = length(var.public_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = var.public_subnet_cidrs[count.index] availability_zone = data.aws_availability_zones.available.names[count.index] map_public_ip_on_launch = true tags = { Name = "${var.project_name}-${var.environment}-public-subnet-${count.index + 1}" Type = "public" } } ######################################## # Private Subnets ######################################## resource "aws_subnet" "private" { count = length(var.private_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = var.private_subnet_cidrs[count.index] availability_zone = data.aws_availability_zones.available.names[count.index] tags = { Name = "${var.project_name}-${var.environment}-private-subnet-${count.index + 1}" Type = "private" } } ######################################## # Internet Gateway ######################################## resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = { Name = "${var.project_name}-${var.environment}-igw" } } ######################################## # Public Route Table ######################################## resource "aws_route_table" "public" { vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id } tags = { Name = "${var.project_name}-${var.environment}-public-rt" } } resource "aws_route_table_association" "public" { count = length(aws_subnet.public) subnet_id = aws_subnet.public[count.index].id route_table_id = aws_route_table.public.id } ######################################## # NAT Gateway (optional) ######################################## resource "aws_eip" "nat" { count = var.create_nat_gateway ? 1 : 0 domain = "vpc" tags = { Name = "${var.project_name}-${var.environment}-nat-eip" } depends_on = [aws_internet_gateway.main] } resource "aws_nat_gateway" "main" { count = var.create_nat_gateway ? 1 : 0 allocation_id = aws_eip.nat[0].id subnet_id = aws_subnet.public[0].id tags = { Name = "${var.project_name}-${var.environment}-nat" } depends_on = [aws_internet_gateway.main] } ######################################## # Private Route Table ######################################## resource "aws_route_table" "private" { vpc_id = aws_vpc.main.id tags = { Name = "${var.project_name}-${var.environment}-private-rt" } } resource "aws_route" "private_nat" { count = var.create_nat_gateway ? 1 : 0 route_table_id = aws_route_table.private.id destination_cidr_block = "0.0.0.0/0" nat_gateway_id = aws_nat_gateway.main[0].id } resource "aws_route_table_association" "private" { count = length(aws_subnet.private) subnet_id = aws_subnet.private[count.index].id route_table_id = aws_route_table.private.id } ######################################## # S3 Bucket for Application Data ######################################## resource "aws_s3_bucket" "app_data" { bucket = "${var.project_name}-${var.environment}-app-data-${random_id.bucket_suffix.hex}" tags = { Name = "${var.project_name}-${var.environment}-app-data" Description = "Application data storage" } } resource "aws_s3_bucket_versioning" "app_data" { bucket = aws_s3_bucket.app_data.id versioning_configuration { status = var.enable_s3_versioning ? "Enabled" : "Disabled" } } resource "aws_s3_bucket_public_access_block" "app_data" { bucket = aws_s3_bucket.app_data.id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } ######################################## # Random ID for unique bucket naming ######################################## resource "random_id" "bucket_suffix" { byte_length = 4 } ######################################## # Data Sources ######################################## data "aws_availability_zones" "available" { state = "available" } data "aws_caller_identity" "current" {} data "aws_region" "current" {}