diff --git a/infra/modules/cognitive-services/cognitiveServices.bicep b/infra/modules/cognitive-services/cognitiveServices.bicep index 765d721..9aa105b 100644 --- a/infra/modules/cognitive-services/cognitiveServices.bicep +++ b/infra/modules/cognitive-services/cognitiveServices.bicep @@ -70,6 +70,9 @@ module cognitiveServicesPrivateDnsZone 'br/public:avm/res/network/private-dns-zo } } +// Ensure private endpoints are created in the VNet's region +var virtualNetworkLocation = resourceGroup().location + module openAiPrivateDnsZone 'br/public:avm/res/network/private-dns-zone:0.7.0' = if (networkIsolation) { name: 'private-dns-openai-deployment' params: { @@ -116,14 +119,15 @@ module aiServices 'service.bicep' = { params: { name: 'cog${name}${resourceToken}' location: location + virtualNetworkLocation: virtualNetworkLocation kind: 'AIServices' category: 'AIServices' networkIsolation: networkIsolation networkAcls: networkAcls virtualNetworkSubnetResourceId: networkIsolation ? virtualNetworkSubnetResourceId : '' privateDnsZonesResourceIds: networkIsolation ? [ - cognitiveServicesPrivateDnsZone.outputs.resourceId - openAiPrivateDnsZone.outputs.resourceId + cognitiveServicesPrivateDnsZone.outputs.?resourceId + openAiPrivateDnsZone.outputs.?resourceId ] : [] logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId @@ -140,12 +144,13 @@ module contentSafety 'service.bicep' = if (contentSafetyEnabled) { params: { name: 'safety${name}${resourceToken}' location: location + virtualNetworkLocation: virtualNetworkLocation kind: 'ContentSafety' networkIsolation: networkIsolation networkAcls: networkAcls virtualNetworkSubnetResourceId: networkIsolation ? virtualNetworkSubnetResourceId : '' privateDnsZonesResourceIds: networkIsolation ? [ - cognitiveServicesPrivateDnsZone.outputs.resourceId + cognitiveServicesPrivateDnsZone.outputs.?resourceId ]: [] logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId roleAssignments: allRoleAssignments @@ -160,13 +165,14 @@ module vision 'service.bicep' = if (visionEnabled) { params: { name: 'vision${name}${resourceToken}' location: location + virtualNetworkLocation: virtualNetworkLocation kind: 'ComputerVision' sku: 'S1' networkIsolation: networkIsolation networkAcls: networkAcls virtualNetworkSubnetResourceId: networkIsolation ? virtualNetworkSubnetResourceId : '' privateDnsZonesResourceIds: networkIsolation ? [ - cognitiveServicesPrivateDnsZone.outputs.resourceId + cognitiveServicesPrivateDnsZone.outputs.?resourceId ] : [] logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId roleAssignments: allRoleAssignments @@ -181,13 +187,14 @@ module language 'service.bicep' = if (languageEnabled) { params: { name: 'lang${name}${resourceToken}' location: location + virtualNetworkLocation: virtualNetworkLocation kind: 'TextAnalytics' sku: 'S' networkIsolation: networkIsolation networkAcls: networkAcls virtualNetworkSubnetResourceId: networkIsolation ? virtualNetworkSubnetResourceId : '' privateDnsZonesResourceIds: networkIsolation ? [ - cognitiveServicesPrivateDnsZone.outputs.resourceId + cognitiveServicesPrivateDnsZone.outputs.?resourceId ] : [] logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId roleAssignments: allRoleAssignments @@ -202,12 +209,13 @@ module speech 'service.bicep' = if (speechEnabled) { params: { name: 'speech${name}${resourceToken}' location: location + virtualNetworkLocation: virtualNetworkLocation kind: 'SpeechServices' networkIsolation: networkIsolation networkAcls: networkAcls virtualNetworkSubnetResourceId: networkIsolation ? virtualNetworkSubnetResourceId : '' privateDnsZonesResourceIds: networkIsolation ? [ - cognitiveServicesPrivateDnsZone.outputs.resourceId + cognitiveServicesPrivateDnsZone.outputs.?resourceId ] : [] logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId roleAssignments: allRoleAssignments @@ -222,13 +230,14 @@ module translator 'service.bicep' = if (translatorEnabled) { params: { name: 'translator${name}${resourceToken}' location: location + virtualNetworkLocation: virtualNetworkLocation kind: 'TextTranslation' sku: 'S1' networkIsolation: networkIsolation networkAcls: networkAcls virtualNetworkSubnetResourceId: networkIsolation ? virtualNetworkSubnetResourceId : '' privateDnsZonesResourceIds: networkIsolation ? [ - cognitiveServicesPrivateDnsZone.outputs.resourceId + cognitiveServicesPrivateDnsZone.outputs.?resourceId ] : [] logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId roleAssignments: allRoleAssignments @@ -243,6 +252,7 @@ module documentIntelligence 'service.bicep' = if (documentIntelligenceEnabled) { params: { name: 'docintel${name}${resourceToken}' location: location + virtualNetworkLocation: virtualNetworkLocation kind: 'FormRecognizer' networkIsolation: networkIsolation virtualNetworkSubnetResourceId: networkIsolation ? virtualNetworkSubnetResourceId : '' @@ -265,9 +275,9 @@ output aiServicesSystemAssignedMIPrincipalId string = aiServices.outputs.?system output connections array = union( [aiServices.outputs.foundryConnection], - contentSafetyEnabled ? [contentSafety.outputs.foundryConnection] : [], - visionEnabled ? [vision.outputs.foundryConnection] : [], - languageEnabled ? [language.outputs.foundryConnection] : [], - speechEnabled ? [speech.outputs.foundryConnection] : [], - translatorEnabled ? [translator.outputs.foundryConnection] : [], - documentIntelligenceEnabled ? [documentIntelligence.outputs.foundryConnection] : []) + contentSafetyEnabled ? [contentSafety.outputs.?foundryConnection] : [], + visionEnabled ? [vision.outputs.?foundryConnection] : [], + languageEnabled ? [language.outputs.?foundryConnection] : [], + speechEnabled ? [speech.outputs.?foundryConnection] : [], + translatorEnabled ? [translator.outputs.?foundryConnection] : [], + documentIntelligenceEnabled ? [documentIntelligence.outputs.?foundryConnection] : []) diff --git a/infra/modules/cognitive-services/service.bicep b/infra/modules/cognitive-services/service.bicep index 828408b..d2d76e4 100644 --- a/infra/modules/cognitive-services/service.bicep +++ b/infra/modules/cognitive-services/service.bicep @@ -59,6 +59,8 @@ param privateDnsZonesResourceIds string[] = [] @description('Resource ID of the subnet for the private endpoint.') param virtualNetworkSubnetResourceId string +@description('Location of the virtual network hosting the private endpoint subnet. Must match the subnet region for private endpoint creation.') +param virtualNetworkLocation string = location @description('The resource ID of the Log Analytics workspace to use for diagnostic settings.') param logAnalyticsWorkspaceResourceId string @@ -114,7 +116,8 @@ module cognitiveServicePrivateEndpoint 'br/public:avm/res/network/private-endpoi name: take('pep-${name}-deployment', 64) params: { name: 'pep-${nameFormatted}-cognitiveservices' - location: location + // Private endpoint must be in same region as the target subnet/VNet + location: virtualNetworkLocation tags: tags privateLinkServiceConnections: [ {