Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 119 additions & 70 deletions DevOps-Project-01/infrastructure/modules/vpc/main.tf
Original file line number Diff line number Diff line change
@@ -1,109 +1,156 @@
# VPC Module
# ========================
# VPC Module - main.tf
# ========================

# ------------------------
# VPC
# ------------------------
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true

tags = {
Name = "${var.environment}-vpc"
Environment = var.environment
}
cidr_block = var.vpc_cidr
enable_dns_hostnames = var.enable_dns_hostnames
enable_dns_support = var.enable_dns_support
instance_tenancy = var.instance_tenancy

tags = merge(
{
Name = var.vpc_name != null ? var.vpc_name : "${var.environment}-vpc"
Environment = var.environment
},
var.tags
)
}

# Internet Gateway
# ------------------------
# Internet Gateway (Optional)
# ------------------------
resource "aws_internet_gateway" "main" {
count = var.enable_internet_gateway ? 1 : 0
vpc_id = aws_vpc.main.id

tags = {
Name = "${var.environment}-igw"
Environment = var.environment
}
tags = merge(
{
Name = "${var.environment}-igw"
Environment = var.environment
},
var.tags
)
}

# ------------------------
# Public Subnets
# ------------------------
resource "aws_subnet" "public" {
count = length(var.public_subnets)
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnets[count.index]
availability_zone = var.azs[count.index]
availability_zone = var.azs[count.index % length(var.azs)]

map_public_ip_on_launch = true

tags = {
Name = "${var.environment}-public-subnet-${count.index + 1}"
Environment = var.environment
}
tags = merge(
{
Name = "${var.environment}-public-subnet-${count.index + 1}"
Environment = var.environment
},
var.tags
)
}

# ------------------------
# Private Subnets
# ------------------------
resource "aws_subnet" "private" {
count = length(var.private_subnets)
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnets[count.index]
availability_zone = var.azs[count.index]

tags = {
Name = "${var.environment}-private-subnet-${count.index + 1}"
Environment = var.environment
}
availability_zone = var.azs[count.index % length(var.azs)]

tags = merge(
{
Name = "${var.environment}-private-subnet-${count.index + 1}"
Environment = var.environment
},
var.tags
)
}

# Elastic IP for NAT Gateway
# ------------------------
# Elastic IPs for NAT Gateway (Optional)
# ------------------------
resource "aws_eip" "nat" {
count = length(var.public_subnets)
count = var.enable_nat_gateway ? var.nat_gateway_count : 0
vpc = true

tags = {
Name = "${var.environment}-nat-eip-${count.index + 1}"
Environment = var.environment
}
tags = merge(
{
Name = "${var.environment}-nat-eip-${count.index + 1}"
Environment = var.environment
},
var.tags
)
}

# NAT Gateway
# ------------------------
# NAT Gateways (Optional)
# ------------------------
resource "aws_nat_gateway" "main" {
count = length(var.public_subnets)
count = var.enable_nat_gateway ? var.nat_gateway_count : 0
allocation_id = aws_eip.nat[count.index].id
subnet_id = aws_subnet.public[count.index].id

tags = {
Name = "${var.environment}-nat-${count.index + 1}"
Environment = var.environment
}
subnet_id = aws_subnet.public[count.index % length(aws_subnet.public)].id

tags = merge(
{
Name = "${var.environment}-nat-${count.index + 1}"
Environment = var.environment
},
var.tags
)
}

# ------------------------
# 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
gateway_id = var.enable_internet_gateway ? aws_internet_gateway.main[0].id : null
}

tags = {
Name = "${var.environment}-public-rt"
Environment = var.environment
}
tags = merge(
{
Name = "${var.environment}-public-rt"
Environment = var.environment
},
var.tags
)
}

# ------------------------
# Private Route Tables
# ------------------------
resource "aws_route_table" "private" {
count = length(var.private_subnets)
vpc_id = aws_vpc.main.id

route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main[count.index].id
nat_gateway_id = var.enable_nat_gateway ? aws_nat_gateway.main[count.index % length(aws_nat_gateway.main)].id : null
}

tags = {
Name = "${var.environment}-private-rt-${count.index + 1}"
Environment = var.environment
}
tags = merge(
{
Name = "${var.environment}-private-rt-${count.index + 1}"
Environment = var.environment
},
var.tags
)
}

# ------------------------
# Route Table Associations
# ------------------------
resource "aws_route_table_association" "public" {
count = length(var.public_subnets)
subnet_id = aws_subnet.public[count.index].id
Expand All @@ -116,25 +163,9 @@ resource "aws_route_table_association" "private" {
route_table_id = aws_route_table.private[count.index].id
}

# VPC Flow Logs
resource "aws_flow_log" "main" {
iam_role_arn = aws_iam_role.flow_log.arn
log_destination = aws_cloudwatch_log_group.flow_log.arn
traffic_type = "ALL"
vpc_id = aws_vpc.main.id
}

# CloudWatch Log Group for VPC Flow Logs
resource "aws_cloudwatch_log_group" "flow_log" {
name = "/aws/vpc/${var.environment}-flow-logs"
retention_in_days = 30

tags = {
Environment = var.environment
}
}

# IAM Role for VPC Flow Logs
# ------------------------
# VPC Flow Logs (Optional but recommended)
# ------------------------
resource "aws_iam_role" "flow_log" {
name = "${var.environment}-vpc-flow-log-role"

Expand All @@ -152,7 +183,6 @@ resource "aws_iam_role" "flow_log" {
})
}

# IAM Role Policy for VPC Flow Logs
resource "aws_iam_role_policy" "flow_log" {
name = "${var.environment}-vpc-flow-log-policy"
role = aws_iam_role.flow_log.id
Expand All @@ -173,4 +203,23 @@ resource "aws_iam_role_policy" "flow_log" {
}
]
})
}
}

resource "aws_cloudwatch_log_group" "flow_log" {
name = "/aws/vpc/${var.environment}-flow-logs"
retention_in_days = 30

tags = merge(
{
Environment = var.environment
},
var.tags
)
}

resource "aws_flow_log" "main" {
iam_role_arn = aws_iam_role.flow_log.arn
log_destination = aws_cloudwatch_log_group.flow_log.arn
traffic_type = "ALL"
vpc_id = aws_vpc.main.id
}
48 changes: 44 additions & 4 deletions DevOps-Project-01/infrastructure/modules/vpc/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
# Essential VPC outputs
output "vpc_id" {
description = "ID of the VPC"
value = aws_vpc.main.id
}

output "vpc_cidr_block" {
description = "CIDR block of the VPC"
value = aws_vpc.main.cidr_block
}

output "vpc_name" {
description = "Name of the VPC from tags"
value = lookup(aws_vpc.main.tags, "Name", null)
}

# Subnets
output "public_subnet_ids" {
description = "List of public subnet IDs"
value = aws_subnet.public[*].id
Expand All @@ -13,12 +25,40 @@ output "private_subnet_ids" {
value = aws_subnet.private[*].id
}

output "public_subnet_cidrs" {
description = "CIDR blocks of public subnets"
value = aws_subnet.public[*].cidr_block
}

output "private_subnet_cidrs" {
description = "CIDR blocks of private subnets"
value = aws_subnet.private[*].cidr_block
}

# NAT Gateways
output "nat_gateway_ids" {
description = "List of NAT Gateway IDs"
value = aws_nat_gateway.main[*].id
}

output "vpc_cidr_block" {
description = "CIDR block of the VPC"
value = aws_vpc.main.cidr_block
}
output "nat_gateway_elastic_ips" {
description = "Elastic IPs associated with NAT Gateways"
value = aws_eip.nat[*].public_ip
}

# Internet Gateway
output "internet_gateway_id" {
description = "ID of the Internet Gateway attached to the VPC"
value = aws_internet_gateway.main.id
}

# Route Tables
output "public_route_table_ids" {
description = "List of public route table IDs"
value = aws_route_table.public[*].id
}

output "private_route_table_ids" {
description = "List of private route table IDs"
value = aws_route_table.private[*].id
}
Loading