Back to Blog
Azure
4 min read

Microsoft Fabric VNET Integration Strategy

Microsoft FabricNetworkingPrivate EndpointsAzureVNET

Microsoft Fabric is powerful for data analytics but integrating it with private Azure resources - storage accounts, databases, Key Vaults behind firewalls - requires planning.

Fabric Networking Landscape

Unlike Azure Synapse, Fabric doesn't have a managed VNET you control. Instead you have:

  1. VNET Data Gateway - Bridge between Fabric and your VNET
  2. Trusted Microsoft Services - Bypass for some Azure services
  3. Managed Private Endpoints (Preview) - Direct private connectivity

Environment Strategy

Typical setup for production:

┌─────────────────────────────────────────────────────────────┐
│                    Azure Tenant                              │
│  ┌─────────────────┐    ┌──────────────────────────────┐   │
│  │  Fabric Tenant  │    │       Azure VNET              │   │
│  │  ┌───────────┐  │    │  ┌─────────────────────────┐ │   │
│  │  │Workspace  │──┼────┼──│ VNET Data Gateway       │ │   │
│  │  │  - NPD    │  │    │  └───────────┬─────────────┘ │   │
│  │  │  - PRD    │  │    │              │               │   │
│  │  └───────────┘  │    │  ┌───────────▼─────────────┐ │   │
│  └─────────────────┘    │  │ Private Endpoints        │ │   │
│                          │  │  - Storage              │ │   │
│                          │  │  - SQL                  │ │   │
│                          │  │  - Key Vault            │ │   │
│                          │  └────────────────────────-┘ │   │
│                          └──────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

Setting Up VNET Data Gateway

1. Create the Subnet

resource "azurerm_subnet" "fabric_gateway" {
  name                 = "snet-fabric-gateway"
  resource_group_name  = azurerm_resource_group.this.name
  virtual_network_name = azurerm_virtual_network.this.name
  address_prefixes     = ["10.0.10.0/24"]

  delegation {
    name = "fabric-delegation"
    service_delegation {
      name    = "Microsoft.PowerPlatform/vnetaccesslinks"
      actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"]
    }
  }
}

2. Create Private Endpoints

For each service Fabric needs to access:

# Storage Account
resource "azurerm_private_endpoint" "storage" {
  name                = "pe-storage-fabric"
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
  subnet_id           = azurerm_subnet.private_endpoints.id

  private_service_connection {
    name                           = "psc-storage"
    private_connection_resource_id = azurerm_storage_account.datalake.id
    subresource_names              = ["dfs"]
    is_manual_connection           = false
  }

  private_dns_zone_group {
    name                 = "dns-group"
    private_dns_zone_ids = [azurerm_private_dns_zone.dfs.id]
  }
}

# SQL Database
resource "azurerm_private_endpoint" "sql" {
  name                = "pe-sql-fabric"
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
  subnet_id           = azurerm_subnet.private_endpoints.id

  private_service_connection {
    name                           = "psc-sql"
    private_connection_resource_id = azurerm_mssql_server.this.id
    subresource_names              = ["sqlServer"]
    is_manual_connection           = false
  }

  private_dns_zone_group {
    name                 = "dns-group"
    private_dns_zone_ids = [azurerm_private_dns_zone.sql.id]
  }
}

3. Configure the Gateway in Fabric

In the Fabric admin portal:

  1. Go to Settings → Manage connections and gateways
  2. Create new VNET data gateway
  3. Select your subscription and VNET
  4. Wait for provisioning (can take 15-30 minutes)

Managed Private Endpoints (Preview)

Fabric now supports managed private endpoints for direct connectivity:

# This is configured in the Fabric portal, not Terraform
# But you can approve the endpoint on the Azure side

resource "azurerm_private_endpoint_connection" "approve_fabric" {
  name                       = "pec-fabric-storage"
  resource_group_name        = azurerm_resource_group.this.name
  private_endpoint_id        = "FABRIC_MANAGED_PE_ID"
  private_service_connection_id = "FABRIC_PSC_ID"
  is_manual_connection       = true
  request_message            = "Approved for Fabric"
  status                     = "Approved"
}

NPD vs PRD Configuration

Non-Production

More relaxed for development velocity:

# Allow Fabric trusted services
resource "azurerm_storage_account" "npd" {
  name                     = "stdatalakenpd"
  resource_group_name      = azurerm_resource_group.npd.name
  location                 = azurerm_resource_group.npd.location
  account_tier             = "Standard"
  account_replication_type = "LRS"

  network_rules {
    default_action = "Deny"
    bypass         = ["AzureServices"]  # Allow Fabric
    ip_rules       = [var.developer_ip]  # Allow dev access
  }
}

Production

Strict - VNET gateway only:

resource "azurerm_storage_account" "prd" {
  name                     = "stdatalakeprd"
  resource_group_name      = azurerm_resource_group.prd.name
  location                 = azurerm_resource_group.prd.location
  account_tier             = "Standard"
  account_replication_type = "GRS"

  network_rules {
    default_action             = "Deny"
    bypass                     = ["None"]  # No bypass
    virtual_network_subnet_ids = [azurerm_subnet.fabric_gateway.id]
  }
}

Testing Connectivity

From a Fabric notebook:

# Test storage connectivity
from notebookutils import mssparkutils

try:
    files = mssparkutils.fs.ls("abfss://[email protected]/")
    print("Storage connectivity: OK")
    for f in files:
        print(f"  {f.name}")
except Exception as e:
    print(f"Storage connectivity: FAILED - {e}")
# Test SQL connectivity
from pyspark.sql import SparkSession

spark = SparkSession.builder.getOrCreate()

try:
    df = spark.read \
        .format("jdbc") \
        .option("url", "jdbc:sqlserver://server.database.windows.net:1433;database=mydb") \
        .option("query", "SELECT 1") \
        .option("authentication", "ActiveDirectoryMSI") \
        .load()
    print("SQL connectivity: OK")
except Exception as e:
    print(f"SQL connectivity: FAILED - {e}")

Performance Considerations

  • VNET gateways add latency (~10-20ms)
  • For large data volumes, consider OneLake shortcuts
  • Position gateway in same region as data sources
  • Use Premium capacity for production workloads

Need help integrating Microsoft Fabric with your Azure infrastructure? Get in touch - we help organisations design secure data platforms.

Need help with your Azure environment?

Get in touch for a free consultation.

Get in Touch