# Nginx Proxy Server Module # Deploys an Nginx reverse proxy to route Cloudflare traffic to backend VMs across regions # Network Interface for Nginx Proxy resource "azurerm_network_interface" "nginx_proxy" { name = "${var.cluster_name}-nginx-nic" location = var.location resource_group_name = var.resource_group_name ip_configuration { name = "internal" subnet_id = var.subnet_id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.nginx_proxy.id } tags = merge(var.tags, { Purpose = "Nginx-Proxy" }) } # Public IP for Nginx Proxy resource "azurerm_public_ip" "nginx_proxy" { name = "${var.cluster_name}-nginx-ip" location = var.location resource_group_name = var.resource_group_name allocation_method = "Static" sku = "Standard" tags = merge(var.tags, { Purpose = "Nginx-Proxy" }) } # Network Security Group for Nginx Proxy resource "azurerm_network_security_group" "nginx_proxy" { name = "${var.cluster_name}-nginx-nsg" location = var.location resource_group_name = var.resource_group_name # Allow HTTP from Cloudflare security_rule { name = "AllowHTTP" priority = 1000 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "80" source_address_prefix = "*" # TODO: Restrict to Cloudflare IP ranges destination_address_prefix = "*" description = "Allow HTTP from Cloudflare" } # Allow HTTPS from Cloudflare security_rule { name = "AllowHTTPS" priority = 1001 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "443" source_address_prefix = "*" # TODO: Restrict to Cloudflare IP ranges destination_address_prefix = "*" description = "Allow HTTPS from Cloudflare" } # Allow SSH for management security_rule { name = "AllowSSH" priority = 1002 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "22" source_address_prefix = "*" # TODO: Restrict to admin IPs destination_address_prefix = "*" description = "Allow SSH for management" } # Allow outbound to backend VMs security_rule { name = "AllowOutboundBackend" priority = 2000 direction = "Outbound" access = "Allow" protocol = "*" source_port_range = "*" destination_port_range = "*" source_address_prefix = "*" destination_address_prefix = "*" description = "Allow outbound to backend VMs" } tags = merge(var.tags, { Purpose = "Network-Security" }) } # Associate NSG with NIC resource "azurerm_network_interface_security_group_association" "nginx_proxy" { network_interface_id = azurerm_network_interface.nginx_proxy.id network_security_group_id = azurerm_network_security_group.nginx_proxy.id } # Virtual Machine for Nginx Proxy resource "azurerm_linux_virtual_machine" "nginx_proxy" { name = "${var.cluster_name}-nginx" location = var.location resource_group_name = var.resource_group_name size = "Standard_D4s_v4" # 4 vCPUs - x64 architecture (compatible with x64 Ubuntu) admin_username = var.admin_username network_interface_ids = [azurerm_network_interface.nginx_proxy.id] admin_ssh_key { username = var.admin_username public_key = var.ssh_public_key } os_disk { name = "${var.cluster_name}-nginx-disk" caching = "ReadWrite" storage_account_type = "Premium_LRS" disk_size_gb = 128 } source_image_reference { publisher = "Canonical" offer = "0001-com-ubuntu-server-jammy" sku = "22_04-lts-gen2" version = "latest" } identity { type = "SystemAssigned" } custom_data = base64encode(templatefile("${path.module}/nginx-cloud-init.yaml", { backend_vms = var.backend_vms admin_username = var.admin_username })) tags = merge(var.tags, { Purpose = "Nginx-Proxy" }) } # Outputs output "fqdn" { value = azurerm_public_ip.nginx_proxy.fqdn description = "FQDN of the Nginx proxy (if DNS configured)" } output "public_ip" { value = azurerm_public_ip.nginx_proxy.ip_address description = "Public IP address of the Nginx proxy" } output "private_ip" { value = azurerm_network_interface.nginx_proxy.private_ip_address description = "Private IP address of the Nginx proxy" } output "principal_id" { value = azurerm_linux_virtual_machine.nginx_proxy.identity[0].principal_id description = "Managed Identity principal ID for Nginx proxy (for Key Vault access)" }