shaikhsalman's picture
refactor: merged structure - model at center, DevSecOps wrapped around it
9d4d5c7 verified
# =============================================================================
# RDS Module — Production-Grade PostgreSQL with Security-First Design
# =============================================================================
# Features:
# - Multi-AZ deployment
# - Encryption at rest (KMS)
# - Encryption in transit (force SSL)
# - Private subnets only (no public access)
# - Automated backups with cross-region replica
# - Performance Insights enabled
# - Enhanced Monitoring enabled
# - Deletion protection enabled
# - Automated major version upgrade controlled
# =============================================================================
resource "aws_db_subnet_group" "this" {
name = "${var.name}-db-subnet-group"
subnet_ids = var.database_subnet_ids
tags = merge(var.tags, {
Name = "${var.name}-db-subnet-group"
})
}
resource "aws_rds_cluster" "this" {
count = var.engine_mode == "serverless" ? 1 : 0
cluster_identifier = "${var.name}-aurora"
engine = var.engine
engine_version = var.engine_version
engine_mode = var.engine_mode
database_name = var.database_name
master_username = var.master_username
master_password = var.master_password
db_subnet_group_name = aws_db_subnet_group.this.name
vpc_security_group_ids = [aws_security_group.rds.id]
storage_encrypted = true
kms_key_id = var.kms_key_arn
backup_retention_period = var.backup_retention_period
preferred_backup_window = "03:00-05:00"
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "${var.name}-final-snapshot"
enable_http_endpoint = var.engine_mode == "serverless"
tags = merge(var.tags, {
Name = "${var.name}-aurora-cluster"
})
}
resource "aws_db_instance" "this" {
count = var.engine_mode != "serverless" ? 1 : 0
identifier = "${var.name}-postgres"
engine = var.engine
engine_version = var.engine_version
instance_class = var.instance_class
allocated_storage = var.allocated_storage
storage_type = "gp3"
storage_encrypted = true
kms_key_id = var.kms_key_arn
db_name = var.database_name
username = var.master_username
password = var.master_password
multi_az = var.multi_az
db_subnet_group_name = aws_db_subnet_group.this.name
vpc_security_group_ids = [aws_security_group.rds.id]
backup_retention_period = var.backup_retention_period
preferred_backup_window = "03:00-05:00"
backup_target = "region"
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "${var.name}-final-snapshot"
performance_insights_enabled = true
performance_insights_kms_key_id = var.kms_key_arn
performance_insights_retention_period = 7
monitoring_interval = 30
monitoring_role_arn = aws_iam_role.rds_monitoring.arn
enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"]
auto_minor_version_upgrade = true
major_engine_version_auto_upgrade = false # Controlled manually
tags = merge(var.tags, {
Name = "${var.name}-postgres"
})
}
# ---------- Security Group: RDS ----------
resource "aws_security_group" "rds" {
name = "${var.name}-rds-sg"
description = "RDS security group - restrict ingress to app tier"
vpc_id = var.vpc_id
# Only allow ingress from application security group
ingress {
description = "PostgreSQL from app tier"
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = var.allowed_security_group_ids
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = merge(var.tags, {
Name = "${var.name}-rds-sg"
})
}
# ---------- RDS Enhanced Monitoring Role ----------
resource "aws_iam_role" "rds_monitoring" {
name = "${var.name}-rds-monitoring-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "monitoring.rds.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "rds_monitoring" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole"
role = aws_iam_role.rds_monitoring.name
}