# ============================================================================= # App Server Droplet # ============================================================================= resource "digitalocean_droplet" "app" { name = "${var.project_name}-app-${var.environment}" size = var.droplet_size image = var.droplet_image region = var.region vpc_uuid = var.vpc_uuid ssh_keys = var.ssh_keys backups = var.enable_backups monitoring = true ipv6 = true user_data = templatefile("${path.module}/cloud-init.yaml.tpl", { ssh_port = var.ssh_port vpc_ip_range = var.vpc_ip_range domain = var.domain forgejo_registry = var.forgejo_registry letsencrypt_email = var.letsencrypt_email }) tags = var.tags lifecycle { create_before_destroy = false ignore_changes = [user_data] } } # ============================================================================= # Firewall # ============================================================================= resource "digitalocean_firewall" "app" { name = "${var.project_name}-app-${var.environment}" droplet_ids = [digitalocean_droplet.app.id] # ========================================================================== # Inbound Rules # ========================================================================== # HTTP (for redirect to HTTPS) inbound_rule { protocol = "tcp" port_range = "80" source_addresses = ["0.0.0.0/0", "::/0"] } # HTTPS inbound_rule { protocol = "tcp" port_range = "443" source_addresses = ["0.0.0.0/0", "::/0"] } # RTMP (streaming ingest) inbound_rule { protocol = "tcp" port_range = "1935" source_addresses = ["0.0.0.0/0", "::/0"] } # SRT (streaming ingest) inbound_rule { protocol = "udp" port_range = "9999" source_addresses = ["0.0.0.0/0", "::/0"] } # WebRTC (ICE candidates) inbound_rule { protocol = "tcp" port_range = "3333" source_addresses = ["0.0.0.0/0", "::/0"] } inbound_rule { protocol = "udp" port_range = "3333" source_addresses = ["0.0.0.0/0", "::/0"] } # WebRTC TCP (fallback) inbound_rule { protocol = "tcp" port_range = "3334" source_addresses = ["0.0.0.0/0", "::/0"] } # HLS/LLHLS streaming inbound_rule { protocol = "tcp" port_range = "8088" source_addresses = ["0.0.0.0/0", "::/0"] } # OME API (internal, but opened for monitoring if needed) inbound_rule { protocol = "tcp" port_range = "8081" source_addresses = [var.vpc_ip_range] } # VPC internal traffic (includes SSH on non-standard port) inbound_rule { protocol = "tcp" port_range = "1-65535" source_addresses = [var.vpc_ip_range] } inbound_rule { protocol = "udp" port_range = "1-65535" source_addresses = [var.vpc_ip_range] } inbound_rule { protocol = "icmp" source_addresses = [var.vpc_ip_range] } # ========================================================================== # Outbound Rules # ========================================================================== # DNS outbound_rule { protocol = "tcp" port_range = "53" destination_addresses = ["0.0.0.0/0", "::/0"] } outbound_rule { protocol = "udp" port_range = "53" destination_addresses = ["0.0.0.0/0", "::/0"] } # HTTP/HTTPS (for pulling images, updates) outbound_rule { protocol = "tcp" port_range = "80" destination_addresses = ["0.0.0.0/0", "::/0"] } outbound_rule { protocol = "tcp" port_range = "443" destination_addresses = ["0.0.0.0/0", "::/0"] } # NTP outbound_rule { protocol = "udp" port_range = "123" destination_addresses = ["0.0.0.0/0", "::/0"] } # VPC internal traffic outbound_rule { protocol = "tcp" port_range = "1-65535" destination_addresses = [var.vpc_ip_range] } outbound_rule { protocol = "udp" port_range = "1-65535" destination_addresses = [var.vpc_ip_range] } outbound_rule { protocol = "icmp" destination_addresses = [var.vpc_ip_range] } } # ============================================================================= # DNS Record (optional) # ============================================================================= resource "digitalocean_record" "app" { count = var.manage_dns ? 1 : 0 domain = var.dns_zone type = "A" name = var.dns_record_name value = digitalocean_droplet.app.ipv4_address ttl = 600 }