open-webui/iac/alb.tf
2025-12-08 11:27:59 +07:00

205 lines
No EOL
4.5 KiB
HCL

# Security group for ALB
resource "aws_security_group" "alb_sg" {
name_prefix = "openwebui-alb-"
vpc_id = var.vpc_id
description = "Security group for OpenWebUI Internal ALB"
# Allow HTTP traffic from Entra proxy and VPN
ingress {
description = "HTTP from Entra Proxy"
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = [var.entra_proxy_ip]
}
ingress {
description = "HTTP from GG VPN"
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = [var.gg_vpn_cidr]
}
egress {
description = "To ECS tasks"
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["192.168.144.0/23"] # VPC CIDR
}
tags = {
Name = "OpenWebUI ALB Security Group"
}
}
# Internal Application Load Balancer
resource "aws_lb" "webui_alb" {
name = "openwebui-internal-alb"
internal = true
load_balancer_type = "application"
security_groups = [aws_security_group.alb_sg.id]
subnets = var.private_subnet_ids
enable_deletion_protection = false
# Access logs (optional)
access_logs {
bucket = aws_s3_bucket.alb_logs.bucket
prefix = "openwebui-alb"
enabled = true
}
tags = {
Name = "OpenWebUI Internal ALB"
}
}
# S3 bucket for ALB access logs
resource "aws_s3_bucket" "alb_logs" {
bucket = "openwebui-alb-logs-${random_id.bucket_suffix.hex}"
force_destroy = true
tags = {
Name = "OpenWebUI ALB Access Logs"
}
}
resource "random_id" "bucket_suffix" {
byte_length = 8
}
resource "aws_s3_bucket_versioning" "alb_logs_versioning" {
bucket = aws_s3_bucket.alb_logs.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "alb_logs_encryption" {
bucket = aws_s3_bucket.alb_logs.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_lifecycle_configuration" "alb_logs_lifecycle" {
bucket = aws_s3_bucket.alb_logs.id
rule {
id = "log_lifecycle"
status = "Enabled"
filter {
prefix = "openwebui-alb/"
}
expiration {
days = 30
}
noncurrent_version_expiration {
noncurrent_days = 7
}
}
}
# ALB bucket policy for access logs
resource "aws_s3_bucket_policy" "alb_logs_policy" {
bucket = aws_s3_bucket.alb_logs.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::127311923021:root" # US East 1 ELB service account
}
Action = "s3:PutObject"
Resource = "${aws_s3_bucket.alb_logs.arn}/openwebui-alb/AWSLogs/${data.aws_caller_identity.current.account_id}/*"
},
{
Effect = "Allow"
Principal = {
Service = "delivery.logs.amazonaws.com"
}
Action = "s3:PutObject"
Resource = "${aws_s3_bucket.alb_logs.arn}/openwebui-alb/AWSLogs/${data.aws_caller_identity.current.account_id}/*"
Condition = {
StringEquals = {
"s3:x-amz-acl" = "bucket-owner-full-control"
}
}
},
{
Effect = "Allow"
Principal = {
Service = "delivery.logs.amazonaws.com"
}
Action = "s3:GetBucketAcl"
Resource = aws_s3_bucket.alb_logs.arn
}
]
})
}
data "aws_caller_identity" "current" {}
# Target group for ECS tasks
resource "aws_lb_target_group" "webui_targets" {
name = "openwebui-targets"
port = 8080
protocol = "HTTP"
vpc_id = var.vpc_id
target_type = "ip"
health_check {
enabled = true
healthy_threshold = 3
unhealthy_threshold = 10
timeout = 15
interval = 60
path = "/health"
matcher = "200"
port = "traffic-port"
protocol = "HTTP"
}
# Enable sticky sessions for session affinity
stickiness {
type = "lb_cookie"
cookie_duration = 86400 # 24 hours
enabled = true
}
tags = {
Name = "OpenWebUI Target Group"
}
# Important: Allow the target group to be recreated
lifecycle {
create_before_destroy = true
}
}
# ALB listener
resource "aws_lb_listener" "webui_listener" {
load_balancer_arn = aws_lb.webui_alb.arn
port = "8080"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.webui_targets.arn
}
tags = {
Name = "OpenWebUI ALB Listener"
}
}