# Load Balancing Module
# Creates Application Load Balancer, Target Group, and Listeners
# Application Load Balancer
resource "aws_lb" "main" {
name = "${var.project_name}-${var.environment}-alb"
internal = false
load_balancer_type = "application"
security_groups = [var.security_group_id]
subnets = var.subnet_ids
enable_deletion_protection = var.environment == "prod" ? true : false
access_logs {
bucket = var.access_logs_bucket != "" ? var.access_logs_bucket : null
prefix = var.access_logs_bucket != "" ? "${var.project_name}-${var.environment}-alb" : null
enabled = var.access_logs_bucket != "" ? true : false
}
tags = merge(
var.tags,
{
Name = "${var.project_name}-${var.environment}-alb"
}
)
}
# Target Group
resource "aws_lb_target_group" "main" {
name = "${var.project_name}-${var.environment}-tg"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
enabled = true
interval = 30
path = var.health_check_path
port = "traffic-port"
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 5
matcher = "200-399"
}
tags = merge(
var.tags,
{
Name = "${var.project_name}-${var.environment}-tg"
}
)
}
# HTTP Listener (redirects to HTTPS)
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
# HTTPS Listener
resource "aws_lb_listener" "https" {
count = var.certificate_arn != "" ? 1 : 0
load_balancer_arn = aws_lb.main.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS-1-2-2017-01"
certificate_arn = var.certificate_arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.main.arn
}
}
# HTTP Listener Rule (if no certificate is provided)
resource "aws_lb_listener_rule" "http_forward" {
count = var.certificate_arn == "" ? 1 : 0
listener_arn = aws_lb_listener.http.arn
priority = 100
action {
type = "forward"
target_group_arn = aws_lb_target_group.main.arn
}
condition {
path_pattern {
values = ["/*"]
}
}
}
# CloudWatch Alarms for ALB
resource "aws_cloudwatch_metric_alarm" "alb_5xx_errors" {
alarm_name = "${var.project_name}-${var.environment}-alb-5xx-errors"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "HTTPCode_ELB_5XX_Count"
namespace = "AWS/ApplicationELB"
period = 300
statistic = "Sum"
threshold = 10
alarm_description = "This alarm monitors ALB 5XX errors"
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
}
alarm_actions = [] # Add SNS topic ARN here if needed
ok_actions = [] # Add SNS topic ARN here if needed
tags = var.tags
}
resource "aws_cloudwatch_metric_alarm" "alb_4xx_errors" {
alarm_name = "${var.project_name}-${var.environment}-alb-4xx-errors"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "HTTPCode_ELB_4XX_Count"
namespace = "AWS/ApplicationELB"
period = 300
statistic = "Sum"
threshold = 100
alarm_description = "This alarm monitors ALB 4XX errors"
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
}
alarm_actions = [] # Add SNS topic ARN here if needed
ok_actions = [] # Add SNS topic ARN here if needed
tags = var.tags
}
resource "aws_cloudwatch_metric_alarm" "alb_target_5xx_errors" {
alarm_name = "${var.project_name}-${var.environment}-alb-target-5xx-errors"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "HTTPCode_Target_5XX_Count"
namespace = "AWS/ApplicationELB"
period = 300
statistic = "Sum"
threshold = 10
alarm_description = "This alarm monitors ALB target 5XX errors"
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
TargetGroup = aws_lb_target_group.main.arn_suffix
}
alarm_actions = [] # Add SNS topic ARN here if needed
ok_actions = [] # Add SNS topic ARN here if needed
tags = var.tags
}
resource "aws_cloudwatch_metric_alarm" "alb_target_response_time" {
alarm_name = "${var.project_name}-${var.environment}-alb-target-response-time"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "TargetResponseTime"
namespace = "AWS/ApplicationELB"
period = 300
statistic = "Average"
threshold = 2 # 2 seconds
alarm_description = "This alarm monitors ALB target response time"
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
TargetGroup = aws_lb_target_group.main.arn_suffix
}
alarm_actions = [] # Add SNS topic ARN here if needed
ok_actions = [] # Add SNS topic ARN here if needed
tags = var.tags
}