Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ param agentSubnetName string = 'agent-subnet'
@description('The name of Private Endpoint subnet to create new or existing subnet for private endpoints')
param peSubnetName string = 'pe-subnet'

@description('The name of MCP subnet for user-deployed Container Apps (e.g., MCP servers)')
param mcpSubnetName string = 'mcp-subnet'

//Existing standard Agent required resources
@description('Existing Virtual Network name Resource ID')
param existingVnetResourceId string = ''
Expand All @@ -84,13 +87,19 @@ param agentSubnetPrefix string = ''
@description('Address prefix for the private endpoint subnet')
param peSubnetPrefix string = ''

@description('Address prefix for the MCP subnet. The default value is 192.168.2.0/24.')
param mcpSubnetPrefix string = ''

@description('The AI Search Service full ARM Resource ID. This is an optional field, and if not provided, the resource will be created.')
param aiSearchResourceId string = ''
@description('The AI Storage Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created.')
param azureStorageAccountResourceId string = ''
@description('The Cosmos DB Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created.')
param azureCosmosDBAccountResourceId string = ''

@description('The Microsoft Fabric Workspace full ARM Resource ID. This is an optional field for Fabric private link connectivity.')
param fabricWorkspaceResourceId string = ''

//New Param for resource group of Private DNS zones
//@description('Optional: Resource group containing existing private DNS zones. If specified, DNS zones will not be created.')
//param existingDnsZonesResourceGroup string = ''
Expand All @@ -99,10 +108,11 @@ param azureCosmosDBAccountResourceId string = ''
param existingDnsZones object = {
'privatelink.services.ai.azure.com': ''
'privatelink.openai.azure.com': ''
'privatelink.cognitiveservices.azure.com': ''
'privatelink.search.windows.net': ''
'privatelink.blob.core.windows.net': ''
'privatelink.documents.azure.com': ''
'privatelink.cognitiveservices.azure.com': ''
'privatelink.search.windows.net': ''
'privatelink.blob.core.windows.net': ''
'privatelink.documents.azure.com': ''
'privatelink.analysis.windows.net': ''
}

@description('Zone Names for Validation of existing Private Dns Zones')
Expand All @@ -113,9 +123,9 @@ param dnsZoneNames array = [
'privatelink.search.windows.net'
'privatelink.blob.core.windows.net'
'privatelink.documents.azure.com'
'privatelink.analysis.windows.net'
]


var projectName = toLower('${firstProjectName}${uniqueSuffix}')
var cosmosDBName = toLower('${aiServices}${uniqueSuffix}cosmosdb')
var aiSearchName = toLower('${aiServices}${uniqueSuffix}search')
Expand All @@ -127,7 +137,6 @@ var searchPassedIn = aiSearchResourceId != ''
var cosmosPassedIn = azureCosmosDBAccountResourceId != ''
var existingVnetPassedIn = existingVnetResourceId != ''


var acsParts = split(aiSearchResourceId, '/')
var aiSearchServiceSubscriptionId = searchPassedIn ? acsParts[2] : subscription().subscriptionId
var aiSearchServiceResourceGroupName = searchPassedIn ? acsParts[4] : resourceGroup().name
Expand Down Expand Up @@ -159,9 +168,11 @@ module vnet 'modules-network-secured/network-agent-vnet.bicep' = {
existingVnetResourceGroupName: vnetResourceGroupName
agentSubnetName: agentSubnetName
peSubnetName: peSubnetName
mcpSubnetName: mcpSubnetName
vnetAddressPrefix: vnetAddressPrefix
agentSubnetPrefix: agentSubnetPrefix
peSubnetPrefix: peSubnetPrefix
mcpSubnetPrefix: mcpSubnetPrefix
existingVnetSubscriptionId: vnetSubscriptionId
}
}
Expand Down Expand Up @@ -220,18 +231,20 @@ module aiDependencies 'modules-network-secured/standard-dependent-resources.bice
// Cosmos DB Account
cosmosDBResourceId: azureCosmosDBAccountResourceId
cosmosDBExists: validateExistingResources.outputs.cosmosDBExists
}
}
}

resource storage 'Microsoft.Storage/storageAccounts@2022-05-01' existing = {
name: aiDependencies.outputs.azureStorageName
scope: resourceGroup(azureStorageSubscriptionId, azureStorageResourceGroupName)
}


resource aiSearch 'Microsoft.Search/searchServices@2023-11-01' existing = {
name: aiDependencies.outputs.aiSearchName
scope: resourceGroup(aiDependencies.outputs.aiSearchServiceSubscriptionId, aiDependencies.outputs.aiSearchServiceResourceGroupName)
scope: resourceGroup(
aiDependencies.outputs.aiSearchServiceSubscriptionId,
aiDependencies.outputs.aiSearchServiceResourceGroupName
)
}

resource cosmosDB 'Microsoft.DocumentDB/databaseAccounts@2024-11-15' existing = {
Expand All @@ -246,31 +259,32 @@ resource cosmosDB 'Microsoft.DocumentDB/databaseAccounts@2024-11-15' existing =
// 3. Links private DNS zones to the VNet for name resolution
// 4. Configures network policies to restrict access to private endpoints only
module privateEndpointAndDNS 'modules-network-secured/private-endpoint-and-dns.bicep' = {
name: '${uniqueSuffix}-private-endpoint'
params: {
aiAccountName: aiAccount.outputs.accountName // AI Services to secure
aiSearchName: aiDependencies.outputs.aiSearchName // AI Search to secure
storageName: aiDependencies.outputs.azureStorageName // Storage to secure
cosmosDBName:aiDependencies.outputs.cosmosDBName
vnetName: vnet.outputs.virtualNetworkName // VNet containing subnets
peSubnetName: vnet.outputs.peSubnetName // Subnet for private endpoints
suffix: uniqueSuffix // Unique identifier
vnetResourceGroupName: vnet.outputs.virtualNetworkResourceGroup
vnetSubscriptionId: vnet.outputs.virtualNetworkSubscriptionId // Subscription ID for the VNet
cosmosDBSubscriptionId: cosmosDBSubscriptionId // Subscription ID for Cosmos DB
cosmosDBResourceGroupName: cosmosDBResourceGroupName // Resource Group for Cosmos DB
aiSearchSubscriptionId: aiSearchServiceSubscriptionId // Subscription ID for AI Search Service
aiSearchResourceGroupName: aiSearchServiceResourceGroupName // Resource Group for AI Search Service
storageAccountResourceGroupName: azureStorageResourceGroupName // Resource Group for Storage Account
storageAccountSubscriptionId: azureStorageSubscriptionId // Subscription ID for Storage Account
existingDnsZones: existingDnsZones
}
dependsOn: [
aiSearch // Ensure AI Search exists
storage // Ensure Storage exists
cosmosDB // Ensure Cosmos DB exists
]
name: '${uniqueSuffix}-private-endpoint'
params: {
aiAccountName: aiAccount.outputs.accountName // AI Services to secure
aiSearchName: aiDependencies.outputs.aiSearchName // AI Search to secure
storageName: aiDependencies.outputs.azureStorageName // Storage to secure
cosmosDBName: aiDependencies.outputs.cosmosDBName
fabricWorkspaceResourceId: fabricWorkspaceResourceId // Microsoft Fabric workspace (optional)
vnetName: vnet.outputs.virtualNetworkName // VNet containing subnets
peSubnetName: vnet.outputs.peSubnetName // Subnet for private endpoints
suffix: uniqueSuffix // Unique identifier
vnetResourceGroupName: vnet.outputs.virtualNetworkResourceGroup
vnetSubscriptionId: vnet.outputs.virtualNetworkSubscriptionId // Subscription ID for the VNet
cosmosDBSubscriptionId: cosmosDBSubscriptionId // Subscription ID for Cosmos DB
cosmosDBResourceGroupName: cosmosDBResourceGroupName // Resource Group for Cosmos DB
aiSearchSubscriptionId: aiSearchServiceSubscriptionId // Subscription ID for AI Search Service
aiSearchResourceGroupName: aiSearchServiceResourceGroupName // Resource Group for AI Search Service
storageAccountResourceGroupName: azureStorageResourceGroupName // Resource Group for Storage Account
storageAccountSubscriptionId: azureStorageSubscriptionId // Subscription ID for Storage Account
existingDnsZones: existingDnsZones
}
dependsOn: [
aiSearch // Ensure AI Search exists
storage // Ensure Storage exists
cosmosDB // Ensure Cosmos DB exists
]
}

/*
Creates a new project (sub-resource of the AI Services account)
Expand Down Expand Up @@ -299,10 +313,10 @@ module aiProject 'modules-network-secured/ai-project-identity.bicep' = {
accountName: aiAccount.outputs.accountName
}
dependsOn: [
privateEndpointAndDNS
cosmosDB
aiSearch
storage
privateEndpointAndDNS
cosmosDB
aiSearch
storage
]
}

Expand All @@ -324,8 +338,8 @@ module storageAccountRoleAssignment 'modules-network-secured/azure-storage-accou
projectPrincipalId: aiProject.outputs.projectPrincipalId
}
dependsOn: [
storage
privateEndpointAndDNS
storage
privateEndpointAndDNS
]
}

Expand Down Expand Up @@ -369,13 +383,13 @@ module addProjectCapabilityHost 'modules-network-secured/add-project-capability-
projectCapHost: projectCapHost
}
dependsOn: [
aiSearch // Ensure AI Search exists
storage // Ensure Storage exists
cosmosDB
privateEndpointAndDNS
cosmosAccountRoleAssignments
storageAccountRoleAssignment
aiSearchRoleAssignments
aiSearch // Ensure AI Search exists
storage // Ensure Storage exists
cosmosDB
privateEndpointAndDNS
cosmosAccountRoleAssignments
storageAccountRoleAssignment
aiSearchRoleAssignments
]
}

Expand All @@ -401,10 +415,9 @@ module cosmosContainerRoleAssignments 'modules-network-secured/cosmos-container-
cosmosAccountName: aiDependencies.outputs.cosmosDBName
projectWorkspaceId: formatProjectWorkspaceId.outputs.projectWorkspaceIdGuid
projectPrincipalId: aiProject.outputs.projectPrincipalId

}
dependsOn: [
addProjectCapabilityHost
storageContainersRoleAssignment
dependsOn: [
addProjectCapabilityHost
storageContainersRoleAssignment
]
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using './main.bicep'

param location = 'eastus2'
param aiServices = 'aiservices'
param location = 'norwayeast'
param aiServices = 'djetchev'
param modelName = 'gpt-4o'
param modelFormat = 'OpenAI'
param modelVersion = '2024-11-20'
param modelSkuName = 'GlobalStandard'
param modelCapacity = 30
param modelSkuName = 'Standard'
param modelCapacity = 1
param firstProjectName = 'project'
param projectDescription = 'A project for the AI Foundry account with network secured deployed Agent'
param displayName = 'project'
Expand All @@ -25,10 +25,10 @@ param azureCosmosDBAccountResourceId = ''
param existingDnsZones = {
'privatelink.services.ai.azure.com': ''
'privatelink.openai.azure.com': ''
'privatelink.cognitiveservices.azure.com': ''
'privatelink.search.windows.net': ''
'privatelink.blob.core.windows.net': ''
'privatelink.documents.azure.com': ''
'privatelink.cognitiveservices.azure.com': ''
'privatelink.search.windows.net': ''
'privatelink.blob.core.windows.net': ''
'privatelink.documents.azure.com': ''
}

//DNSZones names for validating if they exist
Expand All @@ -41,7 +41,6 @@ param dnsZoneNames = [
'privatelink.documents.azure.com'
]


// Network configuration (behavior depends on `existingVnetResourceId`)
//
// - NEW VNet (existingVnetResourceId is empty):
Expand All @@ -65,4 +64,3 @@ param dnsZoneNames = [
param vnetAddressPrefix = ''
param agentSubnetPrefix = ''
param peSubnetPrefix = ''

Loading