Skip to content

VPN Gateway Setup Guide - Point-to-Site Access (DEV ONLY)

⚠️ DEPRECATED (2025-10-24): This guide is for historical reference only. VPN Gateway has been replaced by Azure Bastion + Windows Jump Box VM (ADR-050).

→ See Bastion Dev Access for current recommended approach.

Why deprecated: - High cost (~$360/month for VPN Gateway) - Complex client setup and troubleshooting - Replaced by simpler, cheaper Bastion solution (~$210/month) - Bastion provides browser-based access with Windows environment for UI testing - Cost savings: ~$150/month

Migration: If you have existing VPN Gateway, consider migrating to Bastion (ADR-050).


Historical Documentation (VPN Gateway Approach)

⚠️ Production Note: VPN Gateway is NOT allowed in production. For production environments, use Azure Bastion with a jump box for secure access to private resources.

Overview

This guide walks you through setting up and using the Point-to-Site (P2S) VPN Gateway to access private Azure resources (AI Foundry Studio, Key Vault, etc.) from your local machine.

Environment Support: - ✅ Dev: Supported (default: enabled) - ✅ Staging: Supported (optional) - ❌ Prod: Not supported (use Azure Bastion)

Prerequisites

  • VPN Gateway deployed (see deployment section below)
  • Azure CLI or PowerShell installed
  • Azure VPN Client app installed (download links below)
  • Azure AD account with access to the subscription

Architecture

Your Laptop → VPN Tunnel (encrypted) → Azure VPN Gateway → VNet → Private Endpoints → AI Services, Key Vault, Storage

Once connected: - Access AI Foundry Studio: https://ai.azure.com - Access Azure Portal resources via private IPs - Use Azure CLI/SDKs as if you're on the Azure network


Step 1: Deploy VPN Gateway

VPN Gateway is automatically deployed when deployVpnGateway: true in dev environment.

# Deploy full infrastructure with VPN
./infrastructure/scripts/deploy.sh dev loan-defenders-dev-rg --stage all

# Or deploy VPN separately after infrastructure exists
./infrastructure/scripts/deploy.sh dev loan-defenders-dev-rg --stage vpn

Deployment Time: 30-45 minutes (VPN Gateway provisioning is slow)

Option B: Deploy Using Scripts

# Deploy Layer 1 with VPN Gateway enabled
# Edit infrastructure/bicep/environments/dev.parameters.json
# Set: "deployVpnGateway": { "value": true }

./infrastructure/scripts/deploy-layer1.sh dev

# Note: VPN Gateway deployment takes 30-45 minutes

Or use Azure CLI directly:

az deployment group create \
  --name "layer1-vpn-$(date +%Y%m%d-%H%M%S)" \
  --resource-group "loan-defenders-dev-rg" \
  --template-file "infrastructure/bicep/layer1-foundation.bicep" \
  --parameters "infrastructure/bicep/environments/dev.parameters.json" \
  --verbose

Step 2: Install Azure VPN Client

Download and install the Azure VPN Client for your platform:

Platform Download Link
Windows Microsoft Store - Azure VPN Client
macOS App Store - Azure VPN Client
Linux Manual Install

⚠️ Native VPN Clients NOT Supported: Because this VPN Gateway uses Azure AD authentication with OpenVPN, you MUST use the Azure VPN Client app. Native OS VPN clients (Windows built-in VPN, macOS VPN) do NOT support Azure AD authentication.


Step 3: Download VPN Client Configuration

⚠️ CRITICAL: The VPN Gateway uses Azure AD authentication with OpenVPN protocol ONLY. The authentication method must be EAPTLS, not EapMSChapv2.

# Authenticate to Azure
Connect-AzAccount

# Set subscription
Set-AzContext -SubscriptionId "<your-subscription-id>"

# Generate and download VPN client configuration (Azure AD auth)
$profile = New-AzVpnClientConfiguration `
  -ResourceGroupName "loan-defenders-dev-rg" `
  -VirtualNetworkGatewayName "vpn-gateway-dev" `
  -AuthenticationMethod "EAPTLS"

# Get download URL
Write-Host "Download VPN Profile from:"
Write-Host $profile.VpnProfileSASUrl

# Open browser to download
Start-Process $profile.VpnProfileSASUrl

Azure CLI Method

# Authenticate to Azure
az login

# Generate VPN client configuration (Azure AD auth)
az network vnet-gateway vpn-client generate \
  --resource-group loan-defenders-dev-rg \
  --name vpn-gateway-dev \
  --authentication-method EAPTLS \
  --processor-architecture Amd64

# Output will show download URL - copy and download in browser

This generates a ZIP file containing: - AzureVPN/azurevpnconfig.xml - Azure VPN Client profile (USE THIS) - Generic/VpnSettings.xml - Generic VPN settings - Generic/VpnServerRoot.cer_0 - Server root certificate

⚠️ Important: With Azure AD authentication, you MUST use the AzureVPN/azurevpnconfig.xml file. Native clients (Windows VPN, macOS VPN) are NOT supported with Azure AD authentication.


Step 4: Import Configuration into Azure VPN Client

Windows / macOS

  1. Open Azure VPN Client

  2. Add VPN Connection:

  3. Click "+" (Add connection)
  4. Click "Import"

  5. Select Configuration File:

  6. Navigate to downloaded ZIP
  7. Extract and select: AzureVPN/azurevpnconfig.xml

  8. Configuration Imported:

  9. Connection name: loan-defenders-dev-vpn
  10. VPN Server: Azure VPN Gateway public IP
  11. Authentication: Azure Active Directory

  12. Save

Linux

Note: Linux support for Azure VPN Client requires the official Azure VPN Client for Linux. Follow Microsoft's documentation for Linux setup: https://aka.ms/azvpnclientdownload


⚠️ CRITICAL FIRST-TIME SETUP: Before connecting, you MUST grant admin consent for the Azure VPN Client application.

One-Time Setup (Azure AD Admin Required):

  1. Open the admin consent URL in your browser:
    https://login.microsoftonline.com/{TENANT_ID}/adminconsent?client_id=41b23e61-6c1e-4545-b367-cd054e0ed4b4
    

Replace {TENANT_ID} with your Azure AD tenant ID (find it in Azure Portal → Azure Active Directory → Overview)

  1. Sign in with an Azure AD Global Administrator or Application Administrator account

  2. Review permissions requested by Azure VPN Client:

  3. User.Read
  4. User.ReadBasic.All

  5. Click "Accept" to grant organization-wide consent

  6. Confirmation - You'll see "Permissions granted" message

Why is this required? The Azure VPN Client needs permission to read your Azure AD profile to authenticate the VPN connection. Without admin consent, the VPN tunnel will fail to establish even after successful authentication.


Step 6: Connect to VPN

Azure VPN Client

  1. Open Azure VPN Client

  2. Select Connection:

  3. Click on loan-defenders-dev-vpn

  4. Click "Connect"

  5. Authenticate:

  6. Browser window opens
  7. Sign in with your Azure AD account
  8. Complete MFA if required

  9. Connected!:

  10. Status shows "Connected"
  11. You're now on the Azure VNet

Verify Connection

# Check your VPN IP address (should be in 172.16.0.0/24 range)
ipconfig  # Windows
ifconfig  # macOS/Linux

# Test connectivity to private resources
nslookup loan-defenders-dev-ai.cognitiveservices.azure.com

Step 7: Access AI Foundry Studio

Once connected to VPN:

  1. Open Browser: Navigate to https://ai.azure.com

  2. Sign In: Use your Azure AD credentials

  3. Select Hub: Choose loan-defenders-dev-hub

  4. Access Studio: You now have full access to AI Foundry!

What you can access: - ✅ AI Foundry Studio (model deployments, playground, etc.) - ✅ Azure Portal (private resources) - ✅ Key Vault (via Azure SDK/CLI) - ✅ Storage Account (via Azure SDK/CLI) - ✅ All private endpoints on the VNet


Troubleshooting

Issue: VPN Connection Fails - Authentication Succeeds But Tunnel Doesn't Establish

Symptoms: - Azure AD authentication completes successfully - VPN client shows "Dialing" or "Connecting" - Connection never establishes - No clear error message

Root Cause: VPN Gateway Azure AD configuration uses incorrect issuer URL

Solution - Verify Gateway Configuration:

# Check VPN Gateway Azure AD configuration
az network vnet-gateway show \
  --resource-group loan-defenders-dev-rg \
  --name vpn-gateway-dev \
  --query 'vpnClientConfiguration.{issuer:aadIssuer,tenant:aadTenant,audience:aadAudience,protocols:vpnClientProtocols}'

# Expected output:
# {
#   "issuer": "https://sts.windows.net/{tenant-id}/",  # MUST be sts.windows.net
#   "tenant": "https://login.microsoftonline.com/{tenant-id}/",
#   "audience": "41b23e61-6c1e-4545-b367-cd054e0ed4b4",
#   "protocols": ["OpenVPN"]  # MUST be OpenVPN only for AAD
# }

Critical Requirements: 1. ✅ aadIssuer MUST use https://sts.windows.net/{tenant-id}/ - NOT login.microsoftonline.com 2. ✅ vpnClientProtocols MUST be ["OpenVPN"] only - IKEv2 is incompatible with Azure AD auth 3. ✅ aadAudience must be 41b23e61-6c1e-4545-b367-cd054e0ed4b4 (Azure VPN Client app ID)

If configuration is wrong, redeploy VPN Gateway with corrected Bicep template.

Issue: VPN Gateway Provisioning Fails

Possible Causes: 1. Gateway still provisioning - Wait 30-45 minutes after deployment 2. Incorrect Bicep configuration - Check module parameters

Solution:

# Check VPN Gateway status
Get-AzVirtualNetworkGateway `
  -ResourceGroupName "loan-defenders-dev-rg" `
  -Name "vpn-gateway-dev"

# Look for: ProvisioningState should be "Succeeded"

Issue: Can't Access AI Foundry After Connecting

Verify VPN Connection:

# Check if you got a VPN IP
ipconfig | grep 172.16  # Should show IP in VPN range

# Test DNS resolution
nslookup loan-defenders-dev-ai.cognitiveservices.azure.com

# Test connectivity
ping 10.0.3.4  # Private endpoint subnet IP

Check Private Endpoint DNS:

# Verify private DNS zone records exist
Get-AzPrivateDnsZone -ResourceGroupName loan-defenders-dev-rg
Get-AzPrivateDnsRecordSet -ResourceGroupName loan-defenders-dev-rg -ZoneName "privatelink.cognitiveservices.azure.com"

Issue: "Authentication Failed"

Solution: 1. Ensure you're using correct Azure AD account 2. Check if your account has permissions on the subscription 3. Try re-downloading VPN client configuration 4. Clear browser cache and retry authentication

Issue: Slow VPN Connection

Possible Causes: - VPN Gateway SKU too small (VpnGw1 is basic) - Network congestion - Geographic distance from gateway

Solution:

# Upgrade to VpnGw2 for better performance
$gateway = Get-AzVirtualNetworkGateway `
  -ResourceGroupName "loan-defenders-dev-rg" `
  -Name "vpn-gateway-dev"

$gateway.Sku.Name = "VpnGw2"
$gateway.Sku.Tier = "VpnGw2"

Set-AzVirtualNetworkGateway -VirtualNetworkGateway $gateway

Note: Upgrade costs ~$360/month vs $140/month for VpnGw1


Disconnecting from VPN

Azure VPN Client

  1. Open Azure VPN Client
  2. Click "Disconnect"

Note: VPN Gateway still runs (and costs ~$144/month) even when not connected.


Cost Management

Monthly Costs (VPN Gateway VpnGw1)

  • VPN Gateway: ~$140/month
  • Public IP: ~$3.60/month
  • Total: ~$144/month

Runs 24/7 regardless of connection status.

Alternative: Teardown When Not Needed

If you only need VPN access occasionally:

# Teardown dev environment (removes VPN Gateway)
./infrastructure/scripts/teardown.sh dev loan-defenders-dev-rg --confirm

# Rebuild when needed (30-45 min deployment)
./infrastructure/scripts/deploy.sh dev loan-defenders-dev-rg --stage all

Savings: ~$140/month when torn down


Production Alternative: Azure Bastion

For production environments, use Azure Bastion instead of VPN Gateway:

Advantages: - No client software needed (browser-based) - No open public ports - No client-side configuration - Better audit logging - Lower cost for single-user access

See: Azure Bastion Documentation


Security Best Practices

For Development (VPN Gateway)

  1. ✅ Use Azure AD authentication (no certificate management)
  2. ✅ Enable MFA for all VPN users
  3. ✅ Limit VPN client address pool size
  4. ✅ Monitor VPN connections in Azure Monitor
  5. ✅ Disconnect when not actively working

For Production (Azure Bastion)

  1. ✅ Deploy Bastion in production environments
  2. ✅ Use Just-In-Time (JIT) VM access
  3. ✅ Limit Bastion access via RBAC
  4. ✅ Enable Bastion audit logging
  5. ✅ Use jump boxes instead of direct access

Additional Resources


Summary

  1. ✅ Deploy VPN Gateway (deployVpnGateway: true in dev)
  2. ✅ Install Azure VPN Client
  3. ✅ Download VPN configuration
  4. ✅ Import into Azure VPN Client
  5. ✅ Connect and authenticate
  6. ✅ Access AI Foundry Studio at https://ai.azure.com

Questions? Check the troubleshooting section or refer to Azure documentation.