Securely Integrating Azure API Management with Azure OpenAI via Application Gateway

Architecture Overview

Azure CLI Script for VNet, Subnets, and NSG Configuration

# Variables
$RESOURCE_GROUP="apim-openai-rg"
$LOCATION="eastus"
$VNET_NAME="apim-vnet"
$VNET_ADDRESS_PREFIX="10.0.0.0/16"

# Subnets
$APP_GATEWAY_SUBNET="app-gateway-subnet"
$APP_GATEWAY_SUBNET_PREFIX="10.0.1.0/24"

$APIM_SUBNET="apim-subnet"
$APIM_SUBNET_PREFIX="10.0.2.0/24"

$OPENAI_PE_SUBNET="openai-pe-subnet"
$OPENAI_PE_SUBNET_PREFIX="10.0.3.0/24"

# NSGs
$APP_GATEWAY_NSG="app-gateway-nsg"
$APIM_NSG="apim-nsg"
$OPENAI_PE_NSG="openai-pe-nsg"

# Step 1: Create Resource Group
az group create --name $RESOURCE_GROUP --location $LOCATION

# Step 2: Create Virtual Network
az network vnet create \
    --resource-group $RESOURCE_GROUP \
    --name $VNET_NAME \
    --address-prefix $VNET_ADDRESS_PREFIX \
    --subnet-name $APP_GATEWAY_SUBNET \
    --subnet-prefix $APP_GATEWAY_SUBNET_PREFIX

# Step 3: Create Additional Subnets (APIM & OpenAI Private Endpoint)
az network vnet subnet create \
    --resource-group $RESOURCE_GROUP \
    --vnet-name $VNET_NAME \
    --name $APIM_SUBNET \
    --address-prefix $APIM_SUBNET_PREFIX

az network vnet subnet create \
    --resource-group $RESOURCE_GROUP \
    --vnet-name $VNET_NAME \
    --name $OPENAI_PE_SUBNET \
    --address-prefix $OPENAI_PE_SUBNET_PREFIX

# Step 4: Create NSGs
az network nsg create --resource-group $RESOURCE_GROUP --name $APP_GATEWAY_NSG
az network nsg create --resource-group $RESOURCE_GROUP --name $APIM_NSG
az network nsg create --resource-group $RESOURCE_GROUP --name $OPENAI_PE_NSG

# Step 5: Add NSG Rules for APIM (Allow 3443 for APIM Internal VNet)
az network nsg rule create \
    --resource-group $RESOURCE_GROUP \
    --nsg-name $APIM_NSG \
    --name AllowAPIMInbound3443 \
    --priority 120 \
    --direction Inbound \
    --access Allow \
    --protocol Tcp \
    --source-address-prefixes ApiManagement \
    --destination-address-prefixes VirtualNetwork \
    --destination-port-ranges 3443

# Step 6: Associate NSGs with Subnets
az network vnet subnet update \
    --resource-group $RESOURCE_GROUP \
    --vnet-name $VNET_NAME \
    --name $APP_GATEWAY_SUBNET \
    --network-security-group $APP_GATEWAY_NSG

az network vnet subnet update \
    --resource-group $RESOURCE_GROUP \
    --vnet-name $VNET_NAME \
    --name $APIM_SUBNET \
    --network-security-group $APIM_NSG

az network vnet subnet update \
    --resource-group $RESOURCE_GROUP \
    --vnet-name $VNET_NAME \
    --name $OPENAI_PE_SUBNET \
    --network-security-group $OPENAI_PE_NSG

# Step 7: Configure Service Endpoints for APIM Subnet
az network vnet subnet update \
    --resource-group $RESOURCE_GROUP \
    --vnet-name $VNET_NAME \
    --name $APIM_SUBNET \
    --service-endpoints Microsoft.EventHub Microsoft.KeyVault Microsoft.ServiceBus Microsoft.Sql Microsoft.Storage Microsoft.AzureActiveDirectory Microsoft.CognitiveServices Microsoft.Web

Creating an Azure Open AI with private endpoint

# Create an Azure OpenAI Resource
az cognitiveservices account create \
    --name $AOAI_NAME \
    --resource-group $RESOURCE_GROUP \
    --kind OpenAI \
    --sku S0 \
    --location $LOCATION \
    --yes \
    --custom-domain $AOAI_NAME

#Create a Private Endpoint
az network private-endpoint create \
    --name $PRIVATE_ENDPOINT_NAME \
    --resource-group $RESOURCE_GROUP \
    --vnet-name $VNET_NAME \
    --subnet $SUBNET_NAME \
    --private-connection-resource-id $(az cognitiveservices account show --name $AOAI_NAME --resource-group $RESOURCE_GROUP --query id -o tsv) \
    --group-id account \
    --connection-name "${PRIVATE_ENDPOINT_NAME}-connection"

# Create a Private DNS Zone
az network private-dns zone create \
    --resource-group $RESOURCE_GROUP \
    --name $PRIVATE_DNS_ZONE_NAME

# Link Private DNS Zone to VNet
az network private-dns link vnet create \
    --resource-group $RESOURCE_GROUP \
    --zone-name $PRIVATE_DNS_ZONE_NAME \
    --name "myDNSLink" \
    --virtual-network $VNET_NAME \
    --registration-enabled false

# Retrieve the Private IP Address from the Private Endpoint
PRIVATE_IP=$(az network private-endpoint show \
    --name $PRIVATE_ENDPOINT_NAME \
    --resource-group $RESOURCE_GROUP \
    --query "customDnsConfigs[0].ipAddresses[0]" -o tsv)

# Create a DNS Record for Azure OpenAI
az network private-dns record-set a add-record \
    --resource-group $RESOURCE_GROUP \
    --zone-name $PRIVATE_DNS_ZONE_NAME \
    --record-set-name $AOAI_NAME \
    --ipv4-address $PRIVATE_IP

# Disable Public Network Access
az cognitiveservices account update \
    --name $AOAI_NAME \
    --resource-group $RESOURCE_GROUP \
    --public-network-access Disabled

Last updated