@@ -62,6 +62,8 @@ param keyVaultName string = ''
6262param searchServiceName string = ''
6363@description ('The Azure Search connection name. If ommited will use a default value' )
6464param searchConnectionName string = ''
65+ @description ('The search index name' )
66+ param aiSearchIndexName string = ''
6567@description ('The Azure Storage Account resource name. If ommited will be generated' )
6668param storageAccountName string = ''
6769@description ('The log analytics workspace name. If ommited will be generated' )
@@ -103,7 +105,9 @@ param embedModelFormat string
103105@description ('Name of the embedding model to deploy' )
104106param embedModelName string
105107@description ('Name of the embedding model deployment' )
106- param embedDeploymentName string
108+ param embeddingDeploymentName string
109+ @description ('Embedding model dimensionality' )
110+ param embeddingDeploymentDimensions string
107111
108112@description ('Version of the embedding model to deploy' )
109113// See version availability in this table:
@@ -121,16 +125,20 @@ param embedDeploymentCapacity int
121125
122126param useContainerRegistry bool = true
123127param useApplicationInsights bool = true
124- param useSearch bool = false
128+ @description ('Do we want to use the Azure AI Search' )
129+ param useSearchService bool = false
130+
131+ @description ('Random seed to be used during generation of new resources suffixes.' )
132+ param seed string = newGuid ()
125133
126134var abbrs = loadJsonContent ('./abbreviations.json' )
127- var resourceToken = toLower (uniqueString (subscription ().id , environmentName , location ))
135+ var resourceToken = toLower (uniqueString (subscription ().id , environmentName , location , seed ))
128136var projectName = !empty (aiProjectName ) ? aiProjectName : 'ai-project-${resourceToken }'
129137var tags = { 'azd-env-name' : environmentName }
130138
131139var agentID = !empty (aiAgentID ) ? aiAgentID : ''
132140
133- var aiDeployments = [
141+ var aiChatModel = [
134142 {
135143 name : agentDeploymentName
136144 model : {
@@ -143,8 +151,10 @@ var aiDeployments = [
143151 capacity : agentDeploymentCapacity
144152 }
145153 }
154+ ]
155+ var aiEmbeddingModel = [
146156 {
147- name : embedDeploymentName
157+ name : embeddingDeploymentName
148158 model : {
149159 format : embedModelFormat
150160 name : embedModelName
@@ -157,6 +167,10 @@ var aiDeployments = [
157167 }
158168]
159169
170+ var aiDeployments = concat (
171+ aiChatModel ,
172+ useSearchService ? aiEmbeddingModel : [])
173+
160174//for container and app api
161175param apiAppExists bool = false
162176
@@ -173,6 +187,10 @@ var logAnalyticsWorkspaceResolvedName = !useApplicationInsights
173187 ? logAnalyticsWorkspaceName
174188 : '${abbrs .operationalInsightsWorkspaces }${resourceToken }'
175189
190+ var resolvedSearchServiceName = !useSearchService
191+ ? ''
192+ : !empty (searchServiceName ) ? searchServiceName : '${abbrs .searchSearchServices }${resourceToken }'
193+
176194var containerRegistryResolvedName = !useContainerRegistry
177195 ? ''
178196 : !empty (containerRegistryName ) ? containerRegistryName : '${abbrs .containerRegistryRegistries }${resourceToken }'
@@ -197,15 +215,17 @@ module ai 'core/host/ai-environment.bicep' = if (empty(aiExistingProjectConnecti
197215 ? ''
198216 : !empty (applicationInsightsName ) ? applicationInsightsName : '${abbrs .insightsComponents }${resourceToken }'
199217 containerRegistryName : containerRegistryResolvedName
200- searchServiceName : !useSearch
201- ? ''
202- : !empty (searchServiceName ) ? searchServiceName : '${abbrs .searchSearchServices }${resourceToken }'
203- searchConnectionName : !useSearch
218+ searchServiceName : resolvedSearchServiceName
219+ searchConnectionName : !useSearchService
204220 ? ''
205221 : !empty (searchConnectionName ) ? searchConnectionName : 'search-service-connection'
206222 }
207223}
208224
225+ var searchServiceEndpoint = !useSearchService
226+ ? ''
227+ : ai .outputs .searchServiceEndpoint
228+
209229// If bringing an existing AI project, set up the log analytics workspace here
210230module logAnalytics 'core/monitor/loganalytics.bicep' = if (!empty (aiExistingProjectConnectionString )) {
211231 name : 'logAnalytics'
@@ -222,6 +242,75 @@ var projectConnectionString = empty(hostName)
222242 ? aiExistingProjectConnectionString
223243 : '${hostName };${subscription ().subscriptionId };${rg .name };${projectName }'
224244
245+ var resolvedApplicationInsightsName = !useApplicationInsights || !empty (aiExistingProjectConnectionString )
246+ ? ''
247+ : !empty (applicationInsightsName ) ? applicationInsightsName : '${abbrs .insightsComponents }${resourceToken }'
248+
249+ module monitoringMetricsContribuitorRoleAzureAIDeveloperRG 'core/security/appinsights-access.bicep' = if (!empty (resolvedApplicationInsightsName )) {
250+ name : 'monitoringmetricscontributor-role-azureai-developer-rg'
251+ scope : rg
252+ params : {
253+ appInsightsName : resolvedApplicationInsightsName
254+ principalId : api .outputs .SERVICE_API_IDENTITY_PRINCIPAL_ID
255+ }
256+ }
257+
258+ resource existingProjectRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = if (!empty (aiExistingProjectConnectionString )) {
259+ name : split (aiExistingProjectConnectionString , ';' )[2 ]
260+ }
261+
262+ module userRoleAzureAIDeveloperBackendExistingProjectRG 'core/security/role.bicep' = if (!empty (aiExistingProjectConnectionString )) {
263+ name : 'backend-role-azureai-developer-existing-project-rg'
264+ scope : existingProjectRG
265+ params : {
266+ principalId : api .outputs .SERVICE_API_IDENTITY_PRINCIPAL_ID
267+ roleDefinitionId : '64702f94-c441-49e6-a78b-ef80e0188fee'
268+ }
269+ }
270+
271+ //Container apps host and api
272+ // Container apps host (including container registry)
273+ module containerApps 'core/host/container-apps.bicep' = {
274+ name : 'container-apps'
275+ scope : rg
276+ params : {
277+ name : 'app'
278+ location : location
279+ tags : tags
280+ containerAppsEnvironmentName : 'containerapps-env-${resourceToken }'
281+ containerRegistryName : empty (aiExistingProjectConnectionString )
282+ ? ai .outputs .containerRegistryName
283+ : containerRegistryResolvedName
284+ logAnalyticsWorkspaceName : empty (aiExistingProjectConnectionString )
285+ ? ai .outputs .logAnalyticsWorkspaceName
286+ : logAnalytics .outputs .name
287+ }
288+ }
289+
290+ // API app
291+ module api 'api.bicep' = {
292+ name : 'api'
293+ scope : rg
294+ params : {
295+ name : 'ca-api-${resourceToken }'
296+ location : location
297+ tags : tags
298+ identityName : '${abbrs .managedIdentityUserAssignedIdentities }api-${resourceToken }'
299+ containerAppsEnvironmentName : containerApps .outputs .environmentName
300+ containerRegistryName : containerApps .outputs .registryName
301+ projectConnectionString : projectConnectionString
302+ agentDeploymentName : agentDeploymentName
303+ searchConnectionName : searchConnectionName
304+ aiSearchIndexName : aiSearchIndexName
305+ searchServiceEndpoint : searchServiceEndpoint
306+ embeddingDeploymentName : embeddingDeploymentName
307+ embeddingDeploymentDimensions : embeddingDeploymentDimensions
308+ agentName : agentName
309+ agentID : agentID
310+ exists : apiAppExists
311+ }
312+ }
313+
225314module userAcrRolePush 'core/security/role.bicep' = if (!empty (principalId )) {
226315 name : 'user-role-acr-push'
227316 scope : rg
@@ -267,76 +356,66 @@ module userRoleAzureAIDeveloper 'core/security/role.bicep' = if (!empty(principa
267356 }
268357}
269358
270- module backendRoleAzureAIDeveloperRG 'core/security/role.bicep' = {
271- name : 'backend-role-azureai-developer -rg'
359+ module backendRoleSearchIndexDataContributorRG 'core/security/role.bicep' = if ( useSearchService ) {
360+ name : 'backend-role-azure-index-data-contributor -rg'
272361 scope : rg
273362 params : {
274363 principalId : api .outputs .SERVICE_API_IDENTITY_PRINCIPAL_ID
275- roleDefinitionId : '64702f94-c441-49e6-a78b-ef80e0188fee '
364+ roleDefinitionId : '8ebe5a00-799e-43f5-93ac-243d3dce84a7 '
276365 }
277366}
278367
279- var resolvedApplicationInsightsName = !useApplicationInsights || !empty (aiExistingProjectConnectionString )
280- ? ''
281- : !empty (applicationInsightsName ) ? applicationInsightsName : '${abbrs .insightsComponents }${resourceToken }'
368+ module backendRoleSearchIndexDataReaderRG 'core/security/role.bicep' = if (useSearchService ) {
369+ name : 'backend-role-azure-index-data-reader-rg'
370+ scope : rg
371+ params : {
372+ principalId : api .outputs .SERVICE_API_IDENTITY_PRINCIPAL_ID
373+ roleDefinitionId : '1407120a-92aa-4202-b7e9-c0e197c71c8f'
374+ }
375+ }
282376
283- module monitoringMetricsContribuitorRoleAzureAIDeveloperRG 'core/security/appinsights-access .bicep' = if (! empty ( resolvedApplicationInsightsName ) ) {
284- name : 'monitoringmetricscontributor -role-azureai-developer -rg'
377+ module backendRoleSearchServiceContributorRG 'core/security/role .bicep' = if (useSearchService ) {
378+ name : 'backend -role-azure-search-service-contributor -rg'
285379 scope : rg
286380 params : {
287- appInsightsName : resolvedApplicationInsightsName
288381 principalId : api .outputs .SERVICE_API_IDENTITY_PRINCIPAL_ID
382+ roleDefinitionId : '7ca78c08-252a-4471-8644-bb5ff32d4ba0'
289383 }
290384}
291385
292- resource existingProjectRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = if (!empty (aiExistingProjectConnectionString )) {
293- name : split (aiExistingProjectConnectionString , ';' )[2 ]
386+ module userRoleSearchIndexDataContributorRG 'core/security/role.bicep' = if (useSearchService && !empty (principalId )) {
387+ name : 'user-role-azure-index-data-contributor-rg'
388+ scope : rg
389+ params : {
390+ principalId : principalId
391+ roleDefinitionId : '8ebe5a00-799e-43f5-93ac-243d3dce84a7'
392+ }
294393}
295394
296- module userRoleAzureAIDeveloperBackendExistingProjectRG 'core/security/role.bicep' = if (!empty (aiExistingProjectConnectionString )) {
297- name : 'backend -role-azureai-developer-existing-project -rg'
298- scope : existingProjectRG
395+ module userRoleSearchIndexDataReaderRG 'core/security/role.bicep' = if (useSearchService && !empty (principalId )) {
396+ name : 'user -role-azure-index-data-reader -rg'
397+ scope : rg
299398 params : {
300- principalId : api . outputs . SERVICE_API_IDENTITY_PRINCIPAL_ID
301- roleDefinitionId : '64702f94-c441-49e6-a78b-ef80e0188fee '
399+ principalId : principalId
400+ roleDefinitionId : '1407120a-92aa-4202-b7e9-c0e197c71c8f '
302401 }
303402}
304403
305- //Container apps host and api
306- // Container apps host (including container registry)
307- module containerApps 'core/host/container-apps.bicep' = {
308- name : 'container-apps'
404+ module userRoleSearchServiceContributorRG 'core/security/role.bicep' = if (useSearchService && !empty (principalId )) {
405+ name : 'user-role-azure-search-service-contributor-rg'
309406 scope : rg
310407 params : {
311- name : 'app'
312- location : location
313- tags : tags
314- containerAppsEnvironmentName : 'containerapps-env-${resourceToken }'
315- containerRegistryName : empty (aiExistingProjectConnectionString )
316- ? ai .outputs .containerRegistryName
317- : containerRegistryResolvedName
318- logAnalyticsWorkspaceName : empty (aiExistingProjectConnectionString )
319- ? ai .outputs .logAnalyticsWorkspaceName
320- : logAnalytics .outputs .name
408+ principalId : principalId
409+ roleDefinitionId : '7ca78c08-252a-4471-8644-bb5ff32d4ba0'
321410 }
322411}
323412
324- // API app
325- module api 'api.bicep' = {
326- name : 'api'
413+ module backendRoleAzureAIDeveloperRG 'core/security/role.bicep' = {
414+ name : 'backend-role-azureai-developer-rg'
327415 scope : rg
328416 params : {
329- name : 'ca-api-${resourceToken }'
330- location : location
331- tags : tags
332- identityName : '${abbrs .managedIdentityUserAssignedIdentities }api-${resourceToken }'
333- containerAppsEnvironmentName : containerApps .outputs .environmentName
334- containerRegistryName : containerApps .outputs .registryName
335- projectConnectionString : projectConnectionString
336- agentDeploymentName : agentDeploymentName
337- agentName : agentName
338- agentID : agentID
339- exists : apiAppExists
417+ principalId : api .outputs .SERVICE_API_IDENTITY_PRINCIPAL_ID
418+ roleDefinitionId : '64702f94-c441-49e6-a78b-ef80e0188fee'
340419 }
341420}
342421
@@ -346,6 +425,11 @@ output AZURE_RESOURCE_GROUP string = rg.name
346425output AZURE_TENANT_ID string = tenant ().tenantId
347426output AZURE_AIPROJECT_CONNECTION_STRING string = projectConnectionString
348427output AZURE_AI_AGENT_DEPLOYMENT_NAME string = agentDeploymentName
428+ output AZURE_AI_SEARCH_CONNECTION_NAME string = searchConnectionName
429+ output AZURE_AI_EMBED_DEPLOYMENT_NAME string = embeddingDeploymentName
430+ output AZURE_AI_SEARCH_INDEX_NAME string = aiSearchIndexName
431+ output AZURE_AI_SEARCH_ENDPOINT string = searchServiceEndpoint
432+ output AZURE_AI_EMBED_DIMENSIONS string = embeddingDeploymentDimensions
349433output AZURE_AI_AGENT_NAME string = agentName
350434output AZURE_AI_AGENT_ID string = agentID
351435
0 commit comments