You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

412 lines
14 KiB
HCL

###############################################################################
# Networking Module — Main
# Deploys: Resource Groups, VNets, Subnets, NSGs, NAT Gateway, Peerings
###############################################################################
locals {
prefix = "${var.project}-${var.environment}"
}
# =============================================================================
# Resource Groups (D1 Task 2)
# =============================================================================
resource "azurerm_resource_group" "network" {
name = "rg-${local.prefix}-network"
location = var.location
tags = var.tags
}
resource "azurerm_resource_group" "databricks" {
name = "rg-${local.prefix}-databricks"
location = var.location
tags = var.tags
}
resource "azurerm_resource_group" "storage" {
name = "rg-${local.prefix}-storage"
location = var.location
tags = var.tags
}
resource "azurerm_resource_group" "governance" {
name = "rg-${local.prefix}-governance"
location = var.location
tags = var.tags
}
resource "azurerm_resource_group" "keyvault" {
name = "rg-${local.prefix}-keyvault"
location = var.location
tags = var.tags
}
resource "azurerm_resource_group" "monitoring" {
name = "rg-${local.prefix}-monitoring"
location = var.location
tags = var.tags
}
# =============================================================================
# Main MDP VNet (D1 Task 3)
# =============================================================================
resource "azurerm_virtual_network" "main" {
name = "vnet-${local.prefix}"
location = var.location
resource_group_name = azurerm_resource_group.network.name
address_space = [var.vnet_cidr]
tags = var.tags
}
# --- Databricks Host Subnet ---
resource "azurerm_subnet" "dbx_host" {
name = "snet-${local.prefix}-dbx-host"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = [var.dbx_host_subnet_cidr]
delegation {
name = "databricks-host"
service_delegation {
name = "Microsoft.Databricks/workspaces"
actions = [
"Microsoft.Network/virtualNetworks/subnets/join/action",
"Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
"Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action",
]
}
}
}
# --- Databricks Container Subnet ---
resource "azurerm_subnet" "dbx_container" {
name = "snet-${local.prefix}-dbx-container"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = [var.dbx_container_subnet_cidr]
delegation {
name = "databricks-container"
service_delegation {
name = "Microsoft.Databricks/workspaces"
actions = [
"Microsoft.Network/virtualNetworks/subnets/join/action",
"Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
"Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action",
]
}
}
}
# --- Private Endpoints Subnet ---
resource "azurerm_subnet" "private_endpoints" {
name = "snet-${local.prefix}-pe"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = [var.private_endpoints_subnet_cidr]
private_endpoint_network_policies_enabled = true
}
# =============================================================================
# Transit VNet (Front-End Private Link)
# =============================================================================
resource "azurerm_virtual_network" "transit" {
name = "vnet-${local.prefix}-transit"
location = var.location
resource_group_name = azurerm_resource_group.network.name
address_space = [var.transit_vnet_cidr]
tags = var.tags
}
resource "azurerm_subnet" "transit" {
name = "snet-${local.prefix}-transit"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.transit.name
address_prefixes = [var.transit_subnet_cidr]
private_endpoint_network_policies_enabled = true
}
# =============================================================================
# VNet Peerings
# =============================================================================
# Main VNet <-> Transit VNet
resource "azurerm_virtual_network_peering" "main_to_transit" {
name = "peer-main-to-transit"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.main.name
remote_virtual_network_id = azurerm_virtual_network.transit.id
allow_forwarded_traffic = true
}
resource "azurerm_virtual_network_peering" "transit_to_main" {
name = "peer-transit-to-main"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.transit.name
remote_virtual_network_id = azurerm_virtual_network.main.id
allow_forwarded_traffic = true
}
# Main VNet <-> Hub VNet (if provided)
resource "azurerm_virtual_network_peering" "main_to_hub" {
count = var.hub_vnet_id != "" ? 1 : 0
name = "peer-main-to-hub"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.main.name
remote_virtual_network_id = var.hub_vnet_id
allow_forwarded_traffic = true
allow_gateway_transit = false
use_remote_gateways = true
}
# =============================================================================
# NAT Gateway (stable egress IPs for Databricks subnets)
# =============================================================================
resource "azurerm_public_ip" "nat" {
name = "pip-${local.prefix}-nat"
location = var.location
resource_group_name = azurerm_resource_group.network.name
allocation_method = "Static"
sku = "Standard"
tags = var.tags
}
resource "azurerm_nat_gateway" "main" {
name = "natgw-${local.prefix}"
location = var.location
resource_group_name = azurerm_resource_group.network.name
sku_name = "Standard"
idle_timeout_in_minutes = 10
tags = var.tags
}
resource "azurerm_nat_gateway_public_ip_association" "main" {
nat_gateway_id = azurerm_nat_gateway.main.id
public_ip_address_id = azurerm_public_ip.nat.id
}
resource "azurerm_subnet_nat_gateway_association" "dbx_host" {
subnet_id = azurerm_subnet.dbx_host.id
nat_gateway_id = azurerm_nat_gateway.main.id
}
resource "azurerm_subnet_nat_gateway_association" "dbx_container" {
subnet_id = azurerm_subnet.dbx_container.id
nat_gateway_id = azurerm_nat_gateway.main.id
}
# =============================================================================
# NSGs — Databricks Subnets (see Phase 0 plan §3 NSG Rule Set)
# =============================================================================
resource "azurerm_network_security_group" "dbx" {
name = "nsg-${local.prefix}-dbx"
location = var.location
resource_group_name = azurerm_resource_group.network.name
tags = var.tags
# --- Inbound ---
security_rule {
name = "AllowDatabricksControlPlaneInbound"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "AzureDatabricks"
destination_address_prefix = "*"
}
security_rule {
name = "AllowHostToContainer"
priority = 200
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = var.dbx_host_subnet_cidr
destination_address_prefix = var.dbx_container_subnet_cidr
}
security_rule {
name = "AllowContainerToHost"
priority = 201
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = var.dbx_container_subnet_cidr
destination_address_prefix = var.dbx_host_subnet_cidr
}
security_rule {
name = "DenyAllInbound"
priority = 4096
direction = "Inbound"
access = "Deny"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
# --- Outbound ---
security_rule {
name = "AllowDatabricksControlPlaneOutbound"
priority = 100
direction = "Outbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "AzureDatabricks"
}
security_rule {
name = "AllowSqlOutbound"
priority = 110
direction = "Outbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "3306"
source_address_prefix = "*"
destination_address_prefix = "Sql"
}
security_rule {
name = "AllowStorageOutbound"
priority = 120
direction = "Outbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "Storage"
}
security_rule {
name = "AllowEventHubOutbound"
priority = 130
direction = "Outbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "9093"
source_address_prefix = "*"
destination_address_prefix = "EventHub"
}
security_rule {
name = "AllowPrivateEndpoints"
priority = 200
direction = "Outbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = var.private_endpoints_subnet_cidr
}
security_rule {
name = "DenyInternetOutbound"
priority = 4096
direction = "Outbound"
access = "Deny"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "Internet"
}
}
# --- Associate NSG to both Databricks subnets ---
resource "azurerm_subnet_network_security_group_association" "dbx_host" {
subnet_id = azurerm_subnet.dbx_host.id
network_security_group_id = azurerm_network_security_group.dbx.id
}
resource "azurerm_subnet_network_security_group_association" "dbx_container" {
subnet_id = azurerm_subnet.dbx_container.id
network_security_group_id = azurerm_network_security_group.dbx.id
}
# =============================================================================
# Private DNS Zones
# =============================================================================
resource "azurerm_private_dns_zone" "databricks" {
name = "privatelink.azuredatabricks.net"
resource_group_name = azurerm_resource_group.network.name
tags = var.tags
}
resource "azurerm_private_dns_zone" "dfs" {
name = "privatelink.dfs.core.windows.net"
resource_group_name = azurerm_resource_group.network.name
tags = var.tags
}
resource "azurerm_private_dns_zone" "vault" {
name = "privatelink.vaultcore.azure.net"
resource_group_name = azurerm_resource_group.network.name
tags = var.tags
}
resource "azurerm_private_dns_zone" "purview" {
name = "privatelink.purview.azure.com"
resource_group_name = azurerm_resource_group.network.name
tags = var.tags
}
# --- Link DNS zones to VNets ---
resource "azurerm_private_dns_zone_virtual_network_link" "databricks_main" {
name = "link-dbx-main"
resource_group_name = azurerm_resource_group.network.name
private_dns_zone_name = azurerm_private_dns_zone.databricks.name
virtual_network_id = azurerm_virtual_network.main.id
}
resource "azurerm_private_dns_zone_virtual_network_link" "databricks_transit" {
name = "link-dbx-transit"
resource_group_name = azurerm_resource_group.network.name
private_dns_zone_name = azurerm_private_dns_zone.databricks.name
virtual_network_id = azurerm_virtual_network.transit.id
}
resource "azurerm_private_dns_zone_virtual_network_link" "dfs_main" {
name = "link-dfs-main"
resource_group_name = azurerm_resource_group.network.name
private_dns_zone_name = azurerm_private_dns_zone.dfs.name
virtual_network_id = azurerm_virtual_network.main.id
}
resource "azurerm_private_dns_zone_virtual_network_link" "vault_main" {
name = "link-vault-main"
resource_group_name = azurerm_resource_group.network.name
private_dns_zone_name = azurerm_private_dns_zone.vault.name
virtual_network_id = azurerm_virtual_network.main.id
}
resource "azurerm_private_dns_zone_virtual_network_link" "purview_main" {
name = "link-purview-main"
resource_group_name = azurerm_resource_group.network.name
private_dns_zone_name = azurerm_private_dns_zone.purview.name
virtual_network_id = azurerm_virtual_network.main.id
}