Azure Logic Apps — Standard Logic Apps: VNet Integration
Outbound via VNet, Private Endpoint Inbound, and Hybrid Connectivity
Introduction
Azure Logic Apps Standard provides VNet integration capabilities that enable secure communication with on-premises resources, private endpoints, and other Azure services without exposing them to the public internet. This is essential for enterprise architectures requiring compliance, security, and hybrid cloud scenarios.
This guide covers:
- VNet integration basics — How outbound traffic works
- Private endpoints — Securing inbound access
- On-premises connectivity — Hybrid integration patterns
- Network security — NSG rules and firewall configuration
- Real-world scenarios — Complete implementation patterns
Understanding VNet Integration
Architecture Overview
┌─────────────────────────────────────────────────────────────────────┐
│ LOGIC APPS VNET INTEGRATION ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Azure VNet │ │
│ │ │ │
│ │ ┌──────────────┐ │ │
│ │ │ Logic App │◀── VNet Integration │ │
│ │ │ (App Service)│ (Outbound Traffic) │ │
│ │ └──────────────┘ │ │
│ │ │ │ │
│ │ │ Private Endpoint │ │
│ │ │ (Inbound Traffic) │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ │ │ Private │ │ │
│ │ │ Endpoint │ │ │
│ │ └──────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────┼────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ On-Premises │ │ Azure │ │ Azure │ │
│ │ SQL Server │ │ Key Vault │ │ SQL │ │
│ │ (VPN/Express) │ (Private) │ │ (Private) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
How VNet Integration Works
- Outbound Traffic — Logic App routes traffic through VNet subnet
- Private Endpoints — Traffic arrives via private IP addresses
- On-Premises Access — Use VPN or ExpressRoute for hybrid connectivity
- No Public Exposure — Services only accessible within VNet
Configure VNet Integration
Prerequisites
- Virtual Network — With available subnet
- Delegated Subnet — For App Service integration
- Premium/Standard tier — Logic App Standard tier
- Regional VNet integration — Same region required
Create Logic App with VNet
# Create Logic App with VNet integration during creation
az logicapp create \
--name my-logic-app \
--resource-group my-rg \
--plan my-app-service-plan \
--location eastus \
--storage-account mystorageaccount
# Enable VNet route all
az logicapp config appsettings set \
--name my-logic-app \
--resource-group my-rg \
--settings "WEBSITE_VNET_ROUTE_ALL=1"
# Add VNet integration
az logicapp config vnet-integration add \
--name my-logic-app \
--resource-group my-rg \
--vnet-name my-vnet \
--subnet-name logic-app-subnet
# Verify VNet integration
az logicapp config vnet-integration show \
--name my-logic-app \
--resource-group my-rg
Configure Subnet for Integration
# Create subnet with delegation
az network vnet subnet create \
--name logic-app-subnet \
--vnet-name my-vnet \
--resource-group my-rg \
--address-prefixes 10.0.1.0/24 \
--delegations Microsoft.Web/serverFarms
ARM Template Configuration
{
"resources": [
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name": "my-logic-app",
"location": "eastus",
"properties": {
"virtualNetworkSubnetId": "/subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/logic-app-subnet",
"appSettings": [
{
"name": "WEBSITE_VNET_ROUTE_ALL",
"value": "1"
}
]
}
}
]
}
Private Endpoints for Inbound Access
Create Private Endpoint
# Create private endpoint for Logic App workflow
az network private-endpoint create \
--name logic-app-pe \
--resource-group my-rg \
--location eastus \
--subnet-name private-subnet \
--vnet-name my-vnet \
--connection-name logic-app-connection \
--private-link-service-id /subscriptions/xxx/Microsoft.Logic/workflows/my-logic-app
Private Endpoint for Specific Workflow
# Create private endpoint targeting specific workflow
az network private-endpoint create \
--name order-workflow-pe \
--resource-group my-rg \
--subnet-name private-subnet \
--connection-name order-workflow-connection \
--target-resource /subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.Logic/workflows/my-logic-app/workflows/order-processing
DNS Configuration
{
"dnsConfig": {
"zoneName": "internal.contoso.com",
"privateDnsZoneGroup": {
"zoneConfigs": [
{
"name": "private-endpoint-zone",
"privateDnsZoneId": "/subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.AnalysisServices/servers"
}
]
}
}
}
On-Premises Integration
Connect via VPN Gateway
# Configure Logic App to use VPN
az network vnet-gateway create \
--name vpn-gateway \
--resource-group my-rg \
--location eastus \
--gateway-type Vpn \
--vpn-type RouteBased \
--sku VpnGw1 \
--vnet my-on-prem-vnet
Access On-Premises SQL Server
{
"actions": {
"Query_Orders": {
"type": "Sql",
"inputs": {
"databaseName": "OrdersDB",
"gatewayName": "my-on-prem-gateway",
"query": "SELECT OrderId, CustomerName, Total FROM Orders WHERE Status = @status",
"parameters": {
"status": {
"type": "string",
"value": "pending"
}
}
}
}
}
}
Configure On-Premises Data Gateway
# Install and register data gateway
# Download from: https://aka.ms/gatewayinstall
# Create gateway resource in Azure
az logicapp create \
--name my-gateway \
--resource-group my-rg \
--location eastus
# Add gateway to Logic App
az logicapp update \
--name my-logic-app \
--resource-group my-rg \
--params-file @gateway-config.json
HTTP Call to On-Premises API
{
"triggers": {
"HTTP_Request": {
"type": "Request",
"kind": "Http"
}
},
"actions": {
"Call_On_Prem_API": {
"type": "Http",
"inputs": {
"method": "POST",
"uri": "http://192.168.1.100:8080/api/orders",
"headers": {
"Content-Type": "application/json"
},
"authentication": {
"type": "Basic",
"username": "@appsettings('OnPremUsername')",
"password": "@appsettings('OnPremPassword')"
}
}
}
}
}
Accessing Private Azure Services
Connect to Azure Key Vault
{
"actions": {
"Get_Connection_String": {
"type": "KeyVault",
"inputs": {
"host": {
"connection": {
"name": "keyvault"
}
},
"method": "getSecret",
"parameters": {
"secretName": "storage-connection-string"
}
}
},
"Use_Secret": {
"type": "Http",
"inputs": {
"method": "GET",
"uri": "https://mystorageaccount.blob.core.windows.net/data/file.json",
"authentication": {
"type": "Raw",
"value": "@outputs('Get_Connection_String')"
}
}
}
}
}
Connect to Azure SQL
{
"actions": {
"Query_Customers": {
"type": "Sql",
"inputs": {
"host": {
"connection": {
"name": "azuresql"
}
},
"method": "query",
"databaseName": "CustomerDB",
"query": "SELECT * FROM Customers WHERE Region = @region",
"parameters": {
"region": {
"type": "string",
"value": "US"
}
}
}
}
}
}
Connect to Azure Storage (Private)
{
"actions": {
"Read_Blob": {
"type": "Blob",
"inputs": {
"host": {
"connection": {
"name": "azureblob"
}
},
"method": "read",
"path": "container/file.json"
}
}
}
}
Network Security Configuration
Network Security Groups
{
"securityRules": [
{
"name": "Allow-Ingress-From-VNet",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "443",
"sourceAddressPrefix": "10.0.0.0/16",
"destinationAddressPrefix": "10.0.1.0/24",
"access": "Allow",
"direction": "Inbound",
"priority": 100
},
{
"name": "Allow-LogicApp-To-SQL",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "1433",
"sourceAddressPrefix": "10.0.1.0/24",
"destinationAddressPrefix": "10.0.2.0/24",
"access": "Allow",
"direction": "Outbound",
"priority": 110
},
{
"name": "Deny-Public-Internet",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Deny",
"direction": "Outbound",
"priority": 1000
}
]
}
Application Security Groups
{
"applicationSecurityGroups": [
{
"name": "LogicApps-ASG",
"location": "eastus"
}
]
}
Firewall Rules for On-Premises
# Allow Logic App IP range through firewall
# Outbound ports needed:
# - 443 (HTTPS)
# - 1433 (SQL)
# - 5672 (Service Bus)
# - 11000-11025 (Storage)
# Configure NSG outbound rules
az network nsg rule create \
--nsg-name my-nsg \
--resource-group my-rg \
--name Allow-LogicApp-Outbound \
--protocol Tcp \
--source-address-prefix "10.0.1.0/24" \
--destination-address-prefix "10.0.2.0/24" \
--destination-port-range "*" \
--access Allow \
--priority 100
Complete Workflow Example
Order Processing with Private Services
{
"definition": {
"triggers": {
"When_order_received": {
"type": "ServiceBus",
"inputs": {
"queueName": "orders"
}
}
},
"actions": {
"Get_Order_Details": {
"type": "Sql",
"inputs": {
"databaseName": "OrdersDB",
"gatewayName": "on-prem-gateway",
"query": "SELECT * FROM Orders WHERE OrderId = @orderId",
"parameters": {
"orderId": {
"type": "string",
"value": "@triggerBody()['orderId']"
}
}
}
},
"Call_Inventory_API": {
"type": "Http",
"inputs": {
"method": "POST",
"uri": "http://192.168.1.50/api/inventory/check",
"body": {
"items": "@body('Get_Order_Details')['items']"
}
}
},
"Update_Order_Status": {
"type": "Sql",
"inputs": {
"databaseName": "OrdersDB",
"gatewayName": "on-prem-gateway",
"query": "UPDATE Orders SET Status = @status WHERE OrderId = @orderId",
"parameters": {
"orderId": {
"type": "string",
"value": "@triggerBody()['orderId']"
},
"status": {
"type": "string",
"value": "processed"
}
}
}
},
"Send_Confirmation": {
"type": "KeyVault",
"inputs": {
"operation": "getSecret",
"secretName": "email-api-key"
}
}
}
}
}
Best Practices
| Practice | Description |
|---|---|
| Use private endpoints | Secure inbound access |
| Enable VNet route all | Route all traffic through VNet |
| Implement NSG rules | Control inbound and outbound traffic |
| Use managed identity | Avoid storing credentials |
| Enable diagnostics | Send logs to Log Analytics |
| Use separate subnets | Isolate Logic Apps from other resources |
| Configure DNS | Use private DNS zones |
Troubleshooting
Common Issues
| Issue | Solution |
|---|---|
| Cannot connect to VNet | Verify subnet delegation |
| Private endpoint not accessible | Check DNS resolution |
| On-prem SQL timeout | Check firewall rules, VPN |
| Key Vault access denied | Add Logic App to access policy |
Diagnostic Commands
# Check VNet integration status
az logicapp config vnet-integration show \
--name my-logic-app \
--resource-group my-rg
# Test network connectivity from Logic App
az functionapp show \
--name my-logic-app \
--resource-group my-rg \
--query "outboundIpAddresses"
# Check NSG flow logs
az network nsg show \
--name my-nsg \
--resource-group my-rg
Azure Integration Hub - Advanced Level