@@ -315,7 +315,7 @@ module userAssignedIdentity 'br/public:avm/res/managed-identity/user-assigned-id
315315// WAF recommendations for networking and connectivity: https://learn.microsoft.com/en-us/azure/well-architected/security/networking
316316var networkSecurityGroupBackendResourceName = 'nsg-${solutionSuffix }-backend'
317317module networkSecurityGroupBackend 'br/public:avm/res/network/network-security-group:0.5.1' = if (enablePrivateNetworking ) {
318- name : take ('avm.res.network.network-security-group.${networkSecurityGroupBackendResourceName }' , 64 )
318+ name : take ('avm.res.network.network-security-group.backend. ${networkSecurityGroupBackendResourceName }' , 64 )
319319 params : {
320320 name : networkSecurityGroupBackendResourceName
321321 location : location
@@ -345,7 +345,7 @@ module networkSecurityGroupBackend 'br/public:avm/res/network/network-security-g
345345
346346var networkSecurityGroupBastionResourceName = 'nsg-${solutionSuffix }-bastion'
347347module networkSecurityGroupBastion 'br/public:avm/res/network/network-security-group:0.5.1' = if (enablePrivateNetworking ) {
348- name : take ('avm.res.network.network-security-group.${networkSecurityGroupBastionResourceName }' , 64 )
348+ name : take ('avm.res.network.network-security-group.bastion ${networkSecurityGroupBastionResourceName }' , 64 )
349349 params : {
350350 name : networkSecurityGroupBastionResourceName
351351 location : location
@@ -501,7 +501,7 @@ module networkSecurityGroupBastion 'br/public:avm/res/network/network-security-g
501501
502502var networkSecurityGroupAdministrationResourceName = 'nsg-${solutionSuffix }-administration'
503503module networkSecurityGroupAdministration 'br/public:avm/res/network/network-security-group:0.5.1' = if (enablePrivateNetworking ) {
504- name : take ('avm.res.network.network-security-group.${networkSecurityGroupAdministrationResourceName }' , 64 )
504+ name : take ('avm.res.network.network-security-group.administration. ${networkSecurityGroupAdministrationResourceName }' , 64 )
505505 params : {
506506 name : networkSecurityGroupAdministrationResourceName
507507 location : location
@@ -531,7 +531,7 @@ module networkSecurityGroupAdministration 'br/public:avm/res/network/network-sec
531531
532532var networkSecurityGroupContainersResourceName = 'nsg-${solutionSuffix }-containers'
533533module networkSecurityGroupContainers 'br/public:avm/res/network/network-security-group:0.5.1' = if (enablePrivateNetworking ) {
534- name : take ('avm.res.network.network-security-group.${networkSecurityGroupContainersResourceName }' , 64 )
534+ name : take ('avm.res.network.network-security-group.containers. ${networkSecurityGroupContainersResourceName }' , 64 )
535535 params : {
536536 name : networkSecurityGroupContainersResourceName
537537 location : location
@@ -561,7 +561,7 @@ module networkSecurityGroupContainers 'br/public:avm/res/network/network-securit
561561
562562var networkSecurityGroupWebsiteResourceName = 'nsg-${solutionSuffix }-website'
563563module networkSecurityGroupWebsite 'br/public:avm/res/network/network-security-group:0.5.1' = if (enablePrivateNetworking ) {
564- name : take ('avm.res.network.network-security-group.${networkSecurityGroupWebsiteResourceName }' , 64 )
564+ name : take ('avm.res.network.network-security-group.website. ${networkSecurityGroupWebsiteResourceName }' , 64 )
565565 params : {
566566 name : networkSecurityGroupWebsiteResourceName
567567 location : location
@@ -924,6 +924,8 @@ var privateDnsZones = [
924924 'privatelink.openai.azure.com'
925925 'privatelink.services.ai.azure.com'
926926 'privatelink.documents.azure.com'
927+ 'privatelink.blob.core.windows.net'
928+ 'privatelink.search.windows.net'
927929]
928930
929931// DNS Zone Index Constants
@@ -932,6 +934,8 @@ var dnsZoneIndex = {
932934 openAI : 1
933935 aiServices : 2
934936 cosmosDb : 3
937+ blob : 4
938+ search : 5
935939}
936940
937941// List of DNS zone indices that correspond to AI-related services.
@@ -973,10 +977,10 @@ module avmPrivateDnsZones 'br/public:avm/res/network/private-dns-zone:0.7.1' = [
973977var useExistingAiFoundryAiProject = !empty (existingAiFoundryAiProjectResourceId )
974978var aiFoundryAiServicesResourceGroupName = useExistingAiFoundryAiProject
975979 ? split (existingAiFoundryAiProjectResourceId , '/' )[4 ]
976- : 'rg-${ solutionSuffix }'
980+ : resourceGroup (). name
977981var aiFoundryAiServicesSubscriptionId = useExistingAiFoundryAiProject
978982 ? split (existingAiFoundryAiProjectResourceId , '/' )[2 ]
979- : subscription ().id
983+ : subscription ().subscriptionId
980984var aiFoundryAiServicesResourceName = useExistingAiFoundryAiProject
981985 ? split (existingAiFoundryAiProjectResourceId , '/' )[8 ]
982986 : 'aif-${solutionSuffix }'
@@ -1091,6 +1095,16 @@ module aiFoundryAiServices 'br:mcr.microsoft.com/bicep/avm/res/cognitive-service
10911095 principalId : userAssignedIdentity .outputs .principalId
10921096 principalType : 'ServicePrincipal'
10931097 }
1098+ {
1099+ roleDefinitionIdOrName : '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Azure AI User
1100+ principalId : deployingUserPrincipalId
1101+ principalType : 'User'
1102+ }
1103+ {
1104+ roleDefinitionIdOrName : '64702f94-c441-49e6-a78b-ef80e0188fee' // Azure AI Developer
1105+ principalId : deployingUserPrincipalId
1106+ principalType : 'User'
1107+ }
10941108 ]
10951109 // WAF aligned configuration for Monitoring
10961110 diagnosticSettings : enableMonitoring ? [{ workspaceResourceId : logAnalyticsWorkspaceResourceId }] : null
@@ -1146,6 +1160,9 @@ var aiFoundryAiProjectName = useExistingAiFoundryAiProject
11461160var aiFoundryAiProjectEndpoint = useExistingAiFoundryAiProject
11471161 ? existingAiFoundryAiServicesProject !.properties .endpoints ['AI Foundry API' ]
11481162 : aiFoundryAiServicesProject !.outputs .apiEndpoint
1163+ var aiFoundryAiProjectPrincipalId = useExistingAiFoundryAiProject
1164+ ? existingAiFoundryAiServicesProject !.identity .principalId
1165+ : aiFoundryAiServicesProject !.outputs .principalId
11491166
11501167// ========== Cosmos DB ========== //
11511168// WAF best practices for Cosmos DB: https://learn.microsoft.com/en-us/azure/well-architected/service-guides/cosmos-db
@@ -1187,7 +1204,10 @@ module cosmosDb 'br/public:avm/res/document-db/database-account:0.15.0' = {
11871204 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*'
11881205 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*'
11891206 ]
1190- assignments : [{ principalId : userAssignedIdentity .outputs .principalId }]
1207+ assignments : [
1208+ { principalId : userAssignedIdentity .outputs .principalId }
1209+ { principalId : deployingUserPrincipalId }
1210+ ]
11911211 }
11921212 ]
11931213 // WAF aligned configuration for Monitoring
@@ -1488,7 +1508,7 @@ module containerApp 'br/public:avm/res/app/container-app:0.18.1' = {
14881508 }
14891509 {
14901510 name : 'AZURE_AI_SEARCH_INDEX_NAME'
1491- value : ''
1511+ value : aiSearchIndexName
14921512 }
14931513 {
14941514 name : 'AZURE_AI_SEARCH_ENDPOINT'
@@ -1712,21 +1732,6 @@ module webSite 'modules/web-sites.bicep' = {
17121732
17131733// ========== Storage Account ========== //
17141734
1715- module privateDnsZonesStorageAccount 'br/public:avm/res/network/private-dns-zone:0.7.0' = if (enablePrivateNetworking ) {
1716- name : take ('avm.res.network.private-dns-zone.storage-account.${solutionSuffix }' , 64 )
1717- params : {
1718- name : 'privatelink.blob.core.windows.net'
1719- enableTelemetry : enableTelemetry
1720- virtualNetworkLinks : [
1721- {
1722- name : 'vnetlink-storage-account'
1723- virtualNetworkResourceId : virtualNetwork .outputs .resourceId
1724- }
1725- ]
1726- tags : tags
1727- }
1728- }
1729-
17301735var storageAccountName = replace ('st${solutionSuffix }' , '-' , '' )
17311736param storageContainerName string = 'sample-dataset'
17321737module avmStorageAccount 'br/public:avm/res/storage/storage-account:0.20.0' = {
@@ -1767,15 +1772,16 @@ module avmStorageAccount 'br/public:avm/res/storage/storage-account:0.20.0' = {
17671772 ? [
17681773 {
17691774 name : 'pep-blob-${solutionSuffix }'
1775+ customNetworkInterfaceName : 'nic-blob-${solutionSuffix }'
17701776 privateDnsZoneGroup : {
17711777 privateDnsZoneGroupConfigs : [
17721778 {
17731779 name : 'storage-dns-zone-group-blob'
1774- privateDnsZoneResourceId : privateDnsZonesStorageAccount .outputs .resourceId
1780+ privateDnsZoneResourceId : avmPrivateDnsZones [ dnsZoneIndex . blob ]! .outputs .resourceId
17751781 }
17761782 ]
17771783 }
1778- subnetResourceId : virtualNetwork .outputs .subnetResourceIds [0 ]
1784+ subnetResourceId : virtualNetwork ! .outputs .subnetResourceIds [0 ]
17791785 service : 'blob'
17801786 }
17811787 ]
@@ -1799,22 +1805,8 @@ module avmStorageAccount 'br/public:avm/res/storage/storage-account:0.20.0' = {
17991805
18001806// ========== Search Service ========== //
18011807
1802- module privateDnsZonesSearchService 'br/public:avm/res/network/private-dns-zone:0.7.0' = if (enablePrivateNetworking ) {
1803- name : take ('avm.res.network.private-dns-zone.search-service.${solutionSuffix }' , 64 )
1804- params : {
1805- name : 'privatelink.search.windows.net'
1806- enableTelemetry : enableTelemetry
1807- virtualNetworkLinks : [
1808- {
1809- name : 'vnetlink-search-service'
1810- virtualNetworkResourceId : virtualNetwork .outputs .resourceId
1811- }
1812- ]
1813- tags : tags
1814- }
1815- }
1816-
18171808var searchServiceName = 'srch-${solutionSuffix }'
1809+ var aiSearchIndexName = 'sample-dataset-index'
18181810module searchService 'br/public:avm/res/search/search-service:0.11.1' = {
18191811 name : take ('avm.res.search.search-service.${solutionSuffix }' , 64 )
18201812 params : {
@@ -1835,7 +1827,7 @@ module searchService 'br/public:avm/res/search/search-service:0.11.1' = {
18351827 }
18361828 partitionCount : 1
18371829 replicaCount : 1
1838- sku : 'standard'
1830+ sku : enableScalability ? 'standard' : 'basic '
18391831 tags : tags
18401832 roleAssignments : [
18411833 {
@@ -1848,19 +1840,30 @@ module searchService 'br/public:avm/res/search/search-service:0.11.1' = {
18481840 roleDefinitionIdOrName : 'Search Index Data Contributor'
18491841 principalType : 'User'
18501842 }
1843+ {
1844+ principalId : aiFoundryAiProjectPrincipalId
1845+ roleDefinitionIdOrName : 'Search Index Data Reader'
1846+ principalType : 'ServicePrincipal'
1847+ }
1848+ {
1849+ principalId : aiFoundryAiProjectPrincipalId
1850+ roleDefinitionIdOrName : 'Search Service Contributor'
1851+ principalType : 'ServicePrincipal'
1852+ }
18511853 ]
18521854 privateEndpoints : enablePrivateNetworking
18531855 ? [
18541856 {
18551857 name : 'pep-search-${solutionSuffix }'
1858+ customNetworkInterfaceName : 'nic-search-${solutionSuffix }'
18561859 privateDnsZoneGroup : {
18571860 privateDnsZoneGroupConfigs : [
18581861 {
1859- privateDnsZoneResourceId : privateDnsZonesSearchService .outputs .resourceId
1862+ privateDnsZoneResourceId : avmPrivateDnsZones [ dnsZoneIndex . search ]! .outputs .resourceId
18601863 }
18611864 ]
18621865 }
1863- subnetResourceId : virtualNetwork .outputs .subnetResourceIds [0 ]
1866+ subnetResourceId : virtualNetwork ! .outputs .subnetResourceIds [0 ]
18641867 service : 'searchService'
18651868 }
18661869 ]
@@ -1871,11 +1874,9 @@ module searchService 'br/public:avm/res/search/search-service:0.11.1' = {
18711874// ========== Search Service - AI Project Connection ========== //
18721875
18731876var aiSearchConnectionName = 'aifp-srch-connection-${solutionSuffix }'
1874- var aifSubscriptionId = useExistingAiFoundryAiProject ? split (existingAiFoundryAiProjectResourceId , '/' )[2 ] : subscription ().subscriptionId
1875- var aifResourceGroup = useExistingAiFoundryAiProject ? split (existingAiFoundryAiProjectResourceId , '/' )[4 ] : resourceGroup ().name
1876- module aiSearchFoundryConnection 'modules/aifp_search_connection.bicep' = {
1877+ module aiSearchFoundryConnection 'modules/aifp-connections.bicep' = {
18771878 name : take ('aifp-srch-connection.${solutionSuffix }' , 64 )
1878- scope : resourceGroup (aifSubscriptionId , aifResourceGroup )
1879+ scope : resourceGroup (aiFoundryAiServicesSubscriptionId , aiFoundryAiServicesResourceGroupName )
18791880 params : {
18801881 aiFoundryProjectName : aiFoundryAiProjectName
18811882 aiFoundryName : aiFoundryAiServicesResourceName
@@ -1919,8 +1920,9 @@ output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.outputs.logi
19191920output AZURE_STORAGE_BLOB_URL string = avmStorageAccount .outputs .serviceEndpoints .blob
19201921output AZURE_STORAGE_ACCOUNT_NAME string = storageAccountName
19211922output AZURE_STORAGE_CONTAINER_NAME string = storageContainerName
1922- output AZURE_SEARCH_ENDPOINT string = searchService .outputs .endpoint
1923- output AZURE_SEARCH_NAME string = searchService .outputs .name
1923+ output AZURE_AI_SEARCH_ENDPOINT string = searchService .outputs .endpoint
1924+ output AZURE_AI_SEARCH_NAME string = searchService .outputs .name
1925+ output AZURE_AI_SEARCH_INDEX_NAME string = aiSearchIndexName
19241926
19251927output COSMOSDB_ENDPOINT string = 'https://${cosmosDbResourceName }.documents.azure.com:443/'
19261928output COSMOSDB_DATABASE string = cosmosDbDatabaseName
@@ -1939,5 +1941,5 @@ output AZURE_AI_MODEL_DEPLOYMENT_NAME string = aiFoundryAiServicesModelDeploymen
19391941output AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME string = aiFoundryAiServicesModelDeployment .name
19401942output AZURE_AI_AGENT_ENDPOINT string = aiFoundryAiProjectEndpoint
19411943output APP_ENV string = 'Prod'
1942- output AI_FOUNDRY_RESOURCE_ID string = aiFoundryAiServices .outputs .resourceId
1944+ output AI_FOUNDRY_RESOURCE_ID string = ! useExistingAiFoundryAiProject ? aiFoundryAiServices .outputs .resourceId : existingAiFoundryAiProjectResourceId
19431945output COSMOSDB_ACCOUNT_NAME string = cosmosDbResourceName
0 commit comments