@@ -128,11 +128,15 @@ param searchConnectionId string = ''
128128
129129@description ('The name of the blob container for document storage' )
130130param blobContainerName string = 'documents'
131+ param alwaysReprovision bool = false
131132
132133var abbrs = loadJsonContent ('./abbreviations.json' )
133134
134135var resourceToken = templateValidationMode ? toLower (uniqueString (subscription ().id , environmentName , location , seed )) : toLower (uniqueString (subscription ().id , environmentName , location ))
135136
137+ // Stable token that never depends on `seed` (and therefore never on `newGuid()`).
138+ var resourceTokenStable = toLower (uniqueString (subscription ().id , environmentName , location ))
139+
136140var tags = { 'azd-env-name' : environmentName }
137141
138142var tempAgentID = !empty (aiAgentID ) ? aiAgentID : ''
@@ -188,17 +192,21 @@ var logAnalyticsWorkspaceResolvedName = !useApplicationInsights
188192var resolvedSearchServiceName = !useSearchService
189193 ? ''
190194 : !empty (searchServiceName ) ? searchServiceName : '${abbrs .searchSearchServices }${resourceToken }'
191-
195+ // Storage account name used when we need to reference an existing storage account (must be deterministic for Bicep diagnostics).
196+ // Note: for normal deployments (templateValidationMode == false), resourceTokenStable == resourceToken.
197+ var resolvedStorageAccountName = !empty (storageAccountName )
198+ ? storageAccountName
199+ : '${abbrs .storageStorageAccounts }${resourceTokenStable }'
192200
193- module ai 'core/host/ai-environment.bicep' = if (empty (azureExistingAIProjectResourceId )) {
201+ module ai 'core/host/ai-environment.bicep' = if (empty (azureExistingAIProjectResourceId ) || alwaysReprovision ) {
194202 name : 'ai'
195203 scope : rg
196204 params : {
197205 location : location
198206 tags : tags
199- storageAccountName : ! empty ( storageAccountName )
200- ? storageAccountName
201- : '${ abbrs . storageStorageAccounts }${ resourceToken }'
207+ parentDeploymentName : deployment (). name
208+ deploymentSeed : seed
209+ storageAccountName : resolvedStorageAccountName
202210 aiServicesName : !empty (aiServicesName ) ? aiServicesName : 'aoai-${resourceToken }'
203211 aiProjectName : !empty (aiProjectName ) ? aiProjectName : 'proj-${resourceToken }'
204212 aiServiceModelDeployments : aiDeployments
@@ -224,23 +232,30 @@ var searchServiceEndpoint_final = empty(searchServiceEndpoint) ? searchServiceEn
224232
225233var searchConnectionId_final = empty (searchConnectionId ) ? searchConnectionIdFromAIOutput : searchConnectionId
226234
235+ resource resolvedStorageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
236+ name : resolvedStorageAccountName
237+ scope : rg
238+ }
239+
240+ var storageAccountResourceId_final = resolvedStorageAccount .id
241+
227242// If bringing an existing AI project, set up the log analytics workspace here
228- module logAnalytics 'core/monitor/loganalytics.bicep' = if (!empty (azureExistingAIProjectResourceId )) {
229- name : 'logAnalytics'
243+ module logAnalytics 'core/monitor/loganalytics.bicep' = if (!empty (azureExistingAIProjectResourceId ) && ! alwaysReprovision ) {
244+ name : 'logAnalytics-${ substring ( uniqueString ( deployment (). name , seed ), 0 , 8 )} '
230245 scope : rg
231246 params : {
232247 location : location
233248 tags : tags
234249 name : logAnalyticsWorkspaceResolvedName
235250 }
236251}
237- var existingProjEndpoint = !empty (azureExistingAIProjectResourceId ) ? format ('https://{0}.services.ai.azure.com/api/projects/{1}' ,split (azureExistingAIProjectResourceId , '/' )[8 ], split (azureExistingAIProjectResourceId , '/' )[10 ]) : ''
252+ var existingProjEndpoint = ( !empty (azureExistingAIProjectResourceId ) && ! alwaysReprovision ) ? format ('https://{0}.services.ai.azure.com/api/projects/{1}' ,split (azureExistingAIProjectResourceId , '/' )[8 ], split (azureExistingAIProjectResourceId , '/' )[10 ]) : ''
238253
239- var projectResourceId = !empty (azureExistingAIProjectResourceId )
254+ var projectResourceId = ( !empty (azureExistingAIProjectResourceId ) && ! alwaysReprovision )
240255 ? azureExistingAIProjectResourceId
241256 : ai !.outputs .projectResourceId
242257
243- var projectEndpoint = !empty (azureExistingAIProjectResourceId )
258+ var projectEndpoint = ( !empty (azureExistingAIProjectResourceId ) && ! alwaysReprovision )
244259 ? existingProjEndpoint
245260 : ai !.outputs .aiProjectEndpoint
246261
@@ -258,11 +273,11 @@ module monitoringMetricsContribuitorRoleAzureAIDeveloperRG 'core/security/appins
258273 }
259274}
260275
261- resource existingProjectRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = if (!empty (azureExistingAIProjectResourceId ) && contains (azureExistingAIProjectResourceId , '/' )) {
276+ resource existingProjectRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = if (!empty (azureExistingAIProjectResourceId ) && ! alwaysReprovision && contains (azureExistingAIProjectResourceId , '/' )) {
262277 name : split (azureExistingAIProjectResourceId , '/' )[4 ]
263278}
264279
265- module userRoleAzureAIDeveloperBackendExistingProjectRG 'core/security/role.bicep' = if (!empty (azureExistingAIProjectResourceId )) {
280+ module userRoleAzureAIDeveloperBackendExistingProjectRG 'core/security/role.bicep' = if (!empty (azureExistingAIProjectResourceId ) && ! alwaysReprovision ) {
266281 name : 'backend-role-azureai-developer-existing-project-rg'
267282 scope : existingProjectRG
268283 params : {
@@ -283,7 +298,7 @@ module containerApps 'core/host/container-apps.bicep' = {
283298 containerRegistryName : '${abbrs .containerRegistryRegistries }${resourceToken }'
284299 tags : tags
285300 containerAppsEnvironmentName : 'containerapps-env-${resourceToken }'
286- logAnalyticsWorkspaceName : empty (azureExistingAIProjectResourceId )
301+ logAnalyticsWorkspaceName : empty (azureExistingAIProjectResourceId ) || alwaysReprovision
287302 ? ai !.outputs .logAnalyticsWorkspaceName
288303 : logAnalytics !.outputs .name
289304 }
@@ -313,7 +328,7 @@ module api 'api.bicep' = {
313328 otelInstrumentationGenAICaptureMessageContent : otelInstrumentationGenAICaptureMessageContent
314329 projectEndpoint : projectEndpoint
315330 searchConnectionId : searchConnectionId_final
316- storageAccountResourceId : ai !. outputs . storageAccountId
331+ storageAccountResourceId : storageAccountResourceId_final
317332 blobContainerName : blobContainerName
318333 useAzureAISearch : useSearchService
319334 }
@@ -508,7 +523,7 @@ output AZURE_EXISTING_AGENT_ID string = agentID
508523output AZURE_EXISTING_AIPROJECT_ENDPOINT string = projectEndpoint
509524output ENABLE_AZURE_MONITOR_TRACING bool = enableAzureMonitorTracing
510525output OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT bool = otelInstrumentationGenAICaptureMessageContent
511- output STORAGE_ACCOUNT_RESOURCE_ID string = ai !. outputs . storageAccountId
526+ output STORAGE_ACCOUNT_RESOURCE_ID string = storageAccountResourceId_final
512527output AZURE_BLOB_CONTAINER_NAME string = blobContainerName
513528
514529// Outputs required by azd for ACA
0 commit comments