From b9d4cc0bec3668eedb650d75070df971f2351d1c Mon Sep 17 00:00:00 2001 From: Ajit Padhi Date: Wed, 22 Apr 2026 16:54:05 +0530 Subject: [PATCH 1/2] Optimized resources for deployment --- code/scripts/package_frontend.ps1 | 2 +- code/scripts/package_frontend.sh | 2 +- docker/Frontend.Dockerfile | 2 - infra/main.bicep | 42 +++--- infra/main.json | 198 ++++++++++++++--------------- infra/modules/virtualNetwork.bicep | 2 +- scripts/post_deployment_setup.ps1 | 36 +++--- scripts/post_deployment_setup.sh | 26 ++-- 8 files changed, 152 insertions(+), 158 deletions(-) diff --git a/code/scripts/package_frontend.ps1 b/code/scripts/package_frontend.ps1 index 82b82acdf..aaab72f72 100644 --- a/code/scripts/package_frontend.ps1 +++ b/code/scripts/package_frontend.ps1 @@ -9,5 +9,5 @@ cp backend dist -r -Force # Node cd frontend -npm install +npm ci npm run build diff --git a/code/scripts/package_frontend.sh b/code/scripts/package_frontend.sh index 6b9c9893b..2b5a7b752 100644 --- a/code/scripts/package_frontend.sh +++ b/code/scripts/package_frontend.sh @@ -9,5 +9,5 @@ cp *.py dist cp -r backend dist cd frontend -npm install +npm ci npm run build diff --git a/docker/Frontend.Dockerfile b/docker/Frontend.Dockerfile index 3cb03eb33..c80ec5d59 100644 --- a/docker/Frontend.Dockerfile +++ b/docker/Frontend.Dockerfile @@ -3,11 +3,9 @@ RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app WORKDIR /home/node/app COPY ./code/frontend/package*.json ./ USER node -# RUN npm install --force RUN npm ci COPY --chown=node:node ./code/frontend ./frontend WORKDIR /home/node/app/frontend -RUN npm install --save-dev @types/node @types/jest RUN npm run build FROM python:3.11.7-bookworm diff --git a/infra/main.bicep b/infra/main.bicep index de2bc1968..eed9067ac 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -645,7 +645,7 @@ var dnsZoneIndex = { // - Deploys all zones if no existing Foundry project is used // - Excludes AI-related zones when using with an existing Foundry project // =================================================== -@batchSize(5) +@batchSize(10) module avmPrivateDnsZones './modules/private-dns-zone/private-dns-zone.bicep' = [ for (zone, i) in privateDnsZones: if (enablePrivateNetworking) { name: 'avm.res.network.private-dns-zone.${contains(zone, 'azurecontainerapps.io') ? 'containerappenv' : split(zone, '.')[1]}' @@ -989,7 +989,7 @@ module openai 'modules/core/ai/cognitiveservices.bicep' = { : [] ) } - dependsOn: enablePrivateNetworking ? avmPrivateDnsZones : [] + // Implicit dependency on the specific DNS zone is established via the privateDnsZoneResourceId param reference } module computerVision 'modules/core/ai/cognitiveservices.bicep' = if (useAdvancedImageProcessing) { @@ -1030,7 +1030,7 @@ module computerVision 'modules/core/ai/cognitiveservices.bicep' = if (useAdvance : [] ) } - dependsOn: enablePrivateNetworking ? avmPrivateDnsZones : [] + // Implicit dependency on the specific DNS zone is established via the privateDnsZoneResourceId param reference } // The Web socket from front end application connects to Speech service over a public internet and it does not work over a Private endpoint. @@ -1074,7 +1074,7 @@ module speechService 'modules/core/ai/cognitiveservices.bicep' = { : [] ) } - dependsOn: enablePrivateNetworking ? avmPrivateDnsZones : [] + // Speech service always uses public networking (enablePrivateNetworkingSpeech = false), no DNS zone dependency needed } resource search 'Microsoft.Search/searchServices@2024-06-01-preview' = if (databaseType == 'CosmosDB') { @@ -1230,12 +1230,14 @@ module web 'modules/app/web.bicep' = { { AZURE_BLOB_ACCOUNT_NAME: storageAccountName AZURE_BLOB_CONTAINER_NAME: blobContainerName - AZURE_FORM_RECOGNIZER_ENDPOINT: formrecognizer.outputs.endpoint - AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? computerVision!.outputs.endpoint : '' + // Endpoints constructed from resource names to avoid implicit dependencies on AI service modules, + // enabling parallel deployment of app services and AI services (customSubDomainName defaults to name) + AZURE_FORM_RECOGNIZER_ENDPOINT: 'https://${formRecognizerName}.cognitiveservices.azure.com/' + AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? 'https://${computerVisionName}.cognitiveservices.azure.com/' : '' AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION: computerVisionVectorizeImageApiVersion AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_MODEL_VERSION: computerVisionVectorizeImageModelVersion - AZURE_CONTENT_SAFETY_ENDPOINT: contentsafety.outputs.endpoint - AZURE_KEY_VAULT_ENDPOINT: keyvault.outputs.uri + AZURE_CONTENT_SAFETY_ENDPOINT: 'https://${contentSafetyName}.cognitiveservices.azure.com/' + AZURE_KEY_VAULT_ENDPOINT: 'https://${keyVaultName}${environment().suffixes.keyvaultDns}/' AZURE_OPENAI_RESOURCE: azureOpenAIResourceName AZURE_OPENAI_MODEL: azureOpenAIModel AZURE_OPENAI_MODEL_NAME: azureOpenAIModelName @@ -1253,7 +1255,7 @@ module web 'modules/app/web.bicep' = { AZURE_SPEECH_SERVICE_NAME: speechServiceName AZURE_SPEECH_SERVICE_REGION: location AZURE_SPEECH_RECOGNIZER_LANGUAGES: recognizedLanguages - AZURE_SPEECH_REGION_ENDPOINT: speechService.outputs.endpoint + AZURE_SPEECH_REGION_ENDPOINT: 'https://${speechServiceName}.cognitiveservices.azure.com/' USE_ADVANCED_IMAGE_PROCESSING: useAdvancedImageProcessing ? 'true' : 'false' ADVANCED_IMAGE_PROCESSING_MAX_IMAGES: string(advancedImageProcessingMaxImages) ORCHESTRATION_STRATEGY: orchestrationStrategy @@ -1333,12 +1335,13 @@ module adminweb 'modules/app/adminweb.bicep' = { { AZURE_BLOB_ACCOUNT_NAME: storageAccountName AZURE_BLOB_CONTAINER_NAME: blobContainerName - AZURE_FORM_RECOGNIZER_ENDPOINT: formrecognizer.outputs.endpoint - AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? computerVision!.outputs.endpoint : '' + // Endpoints constructed from resource names to avoid implicit dependencies on AI service modules + AZURE_FORM_RECOGNIZER_ENDPOINT: 'https://${formRecognizerName}.cognitiveservices.azure.com/' + AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? 'https://${computerVisionName}.cognitiveservices.azure.com/' : '' AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION: computerVisionVectorizeImageApiVersion AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_MODEL_VERSION: computerVisionVectorizeImageModelVersion - AZURE_CONTENT_SAFETY_ENDPOINT: contentsafety.outputs.endpoint - AZURE_KEY_VAULT_ENDPOINT: keyvault.outputs.uri + AZURE_CONTENT_SAFETY_ENDPOINT: 'https://${contentSafetyName}.cognitiveservices.azure.com/' + AZURE_KEY_VAULT_ENDPOINT: 'https://${keyVaultName}${environment().suffixes.keyvaultDns}/' AZURE_OPENAI_RESOURCE: azureOpenAIResourceName AZURE_OPENAI_MODEL: azureOpenAIModel AZURE_OPENAI_MODEL_NAME: azureOpenAIModelName @@ -1440,12 +1443,13 @@ module function 'modules/app/function.bicep' = { { AZURE_BLOB_ACCOUNT_NAME: storageAccountName AZURE_BLOB_CONTAINER_NAME: blobContainerName - AZURE_FORM_RECOGNIZER_ENDPOINT: formrecognizer.outputs.endpoint - AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? computerVision!.outputs.endpoint : '' + // Endpoints constructed from resource names to avoid implicit dependencies on AI service modules + AZURE_FORM_RECOGNIZER_ENDPOINT: 'https://${formRecognizerName}.cognitiveservices.azure.com/' + AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? 'https://${computerVisionName}.cognitiveservices.azure.com/' : '' AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION: computerVisionVectorizeImageApiVersion AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_MODEL_VERSION: computerVisionVectorizeImageModelVersion - AZURE_CONTENT_SAFETY_ENDPOINT: contentsafety.outputs.endpoint - AZURE_KEY_VAULT_ENDPOINT: keyvault.outputs.uri + AZURE_CONTENT_SAFETY_ENDPOINT: 'https://${contentSafetyName}.cognitiveservices.azure.com/' + AZURE_KEY_VAULT_ENDPOINT: 'https://${keyVaultName}${environment().suffixes.keyvaultDns}/' AZURE_OPENAI_MODEL: azureOpenAIModel AZURE_OPENAI_MODEL_NAME: azureOpenAIModelName AZURE_OPENAI_MODEL_VERSION: azureOpenAIModelVersion @@ -1571,7 +1575,7 @@ module formrecognizer 'modules/core/ai/cognitiveservices.bicep' = { : [] ) } - dependsOn: enablePrivateNetworking ? avmPrivateDnsZones : [] + // Implicit dependency on the specific DNS zone is established via the privateDnsZoneResourceId param reference } module contentsafety 'modules/core/ai/cognitiveservices.bicep' = { @@ -1611,7 +1615,7 @@ module contentsafety 'modules/core/ai/cognitiveservices.bicep' = { : [] ) } - dependsOn: enablePrivateNetworking ? avmPrivateDnsZones : [] + // Implicit dependency on the specific DNS zone is established via the privateDnsZoneResourceId param reference } // If advanced image processing is used, storage account already should be publicly accessible. diff --git a/infra/main.json b/infra/main.json index a326f5d12..b0881f150 100644 --- a/infra/main.json +++ b/infra/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "7917528723591220424" + "version": "0.41.2.15936", + "templateHash": "13064725685019502849" } }, "parameters": { @@ -773,8 +773,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "10505014921320408169" + "version": "0.41.2.15936", + "templateHash": "1910038870536510356" } }, "definitions": { @@ -1163,7 +1163,7 @@ "name": "nsgs", "count": "[length(parameters('subnets'))]", "mode": "serial", - "batchSize": 1 + "batchSize": 4 }, "condition": "[not(empty(tryGet(parameters('subnets')[copyIndex()], 'networkSecurityGroup')))]", "type": "Microsoft.Resources/deployments", @@ -14093,7 +14093,7 @@ "name": "avmPrivateDnsZones", "count": "[length(variables('privateDnsZones'))]", "mode": "serial", - "batchSize": 5 + "batchSize": 10 }, "condition": "[parameters('enablePrivateNetworking')]", "type": "Microsoft.Resources/deployments", @@ -14130,8 +14130,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "540205332443050509" + "version": "0.41.2.15936", + "templateHash": "16522626459400994678" }, "name": "Private DNS Zones", "description": "This module deploys a Private DNS zone." @@ -14365,8 +14365,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "8870639393421595019" + "version": "0.41.2.15936", + "templateHash": "11851525189118797157" }, "name": "Private DNS Zone Virtual Network Link", "description": "This module deploys a Private DNS Zone Virtual Network Link." @@ -14577,8 +14577,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "11711513794317134129" + "version": "0.41.2.15936", + "templateHash": "3268139627638994011" }, "name": "Azure Cosmos DB account", "description": "This module deploys an Azure Cosmos DB account. The API used for the account is determined by the child resources that are deployed." @@ -15917,8 +15917,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "8126051935459764068" + "version": "0.41.2.15936", + "templateHash": "7264846420703255600" }, "name": "DocumentDB Database Account SQL Databases", "description": "This module deploys a SQL Database in a CosmosDB Account." @@ -16049,8 +16049,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "13853837980194487183" + "version": "0.41.2.15936", + "templateHash": "124073885262920691" }, "name": "DocumentDB Database Account SQL Database Containers", "description": "This module deploys a SQL Database Container in a CosmosDB Account." @@ -16303,8 +16303,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "4008283578727572018" + "version": "0.41.2.15936", + "templateHash": "16935264052800773961" }, "name": "DocumentDB Database Account SQL Role Definitions.", "description": "This module deploys a SQL Role Definision in a CosmosDB Account." @@ -16440,8 +16440,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "12168486909939638829" + "version": "0.41.2.15936", + "templateHash": "13391456638579008263" }, "name": "DocumentDB Database Account SQL Role Assignments.", "description": "This module deploys a SQL Role Assignment in a CosmosDB Account." @@ -20224,8 +20224,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "5629769134054094975" + "version": "0.41.2.15936", + "templateHash": "12461832127590566376" }, "name": "Key Vaults", "description": "This module deploys a Key Vault." @@ -21239,8 +21239,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "9745916835586548568" + "version": "0.41.2.15936", + "templateHash": "17638768712999286282" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret." @@ -22392,8 +22392,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "11466056601858560902" + "version": "0.41.2.15936", + "templateHash": "9897399857943770193" } }, "parameters": { @@ -22611,8 +22611,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "663091920696574433" + "version": "0.41.2.15936", + "templateHash": "1086305767743367425" }, "name": "Cognitive Services", "description": "This module deploys a Cognitive Service." @@ -24942,7 +24942,7 @@ } }, "dependsOn": [ - "avmPrivateDnsZones", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)]", "managedIdentityModule", "monitoring", "virtualNetwork" @@ -24998,8 +24998,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "11466056601858560902" + "version": "0.41.2.15936", + "templateHash": "9897399857943770193" } }, "parameters": { @@ -25217,8 +25217,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "663091920696574433" + "version": "0.41.2.15936", + "templateHash": "1086305767743367425" }, "name": "Cognitive Services", "description": "This module deploys a Cognitive Service." @@ -27548,7 +27548,7 @@ } }, "dependsOn": [ - "avmPrivateDnsZones", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]", "managedIdentityModule", "monitoring", "virtualNetwork" @@ -27605,8 +27605,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "11466056601858560902" + "version": "0.41.2.15936", + "templateHash": "9897399857943770193" } }, "parameters": { @@ -27824,8 +27824,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "663091920696574433" + "version": "0.41.2.15936", + "templateHash": "1086305767743367425" }, "name": "Cognitive Services", "description": "This module deploys a Cognitive Service." @@ -30155,7 +30155,7 @@ } }, "dependsOn": [ - "avmPrivateDnsZones", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]", "managedIdentityModule", "monitoring", "virtualNetwork" @@ -33138,7 +33138,7 @@ }, "applicationInsightsName": "[if(parameters('enableMonitoring'), createObject('value', reference('monitoring').outputs.applicationInsightsName.value), createObject('value', ''))]", "appSettings": { - "value": "[union(createObject('AZURE_BLOB_ACCOUNT_NAME', variables('storageAccountName'), 'AZURE_BLOB_CONTAINER_NAME', variables('blobContainerName'), 'AZURE_FORM_RECOGNIZER_ENDPOINT', reference('formrecognizer').outputs.endpoint.value, 'AZURE_COMPUTER_VISION_ENDPOINT', if(parameters('useAdvancedImageProcessing'), reference('computerVision').outputs.endpoint.value, ''), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION', parameters('computerVisionVectorizeImageApiVersion'), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_MODEL_VERSION', parameters('computerVisionVectorizeImageModelVersion'), 'AZURE_CONTENT_SAFETY_ENDPOINT', reference('contentsafety').outputs.endpoint.value, 'AZURE_KEY_VAULT_ENDPOINT', reference('keyvault').outputs.uri.value, 'AZURE_OPENAI_RESOURCE', variables('azureOpenAIResourceName'), 'AZURE_OPENAI_MODEL', parameters('azureOpenAIModel'), 'AZURE_OPENAI_MODEL_NAME', parameters('azureOpenAIModelName'), 'AZURE_OPENAI_MODEL_VERSION', parameters('azureOpenAIModelVersion'), 'AZURE_OPENAI_TEMPERATURE', parameters('azureOpenAITemperature'), 'AZURE_OPENAI_TOP_P', parameters('azureOpenAITopP'), 'AZURE_OPENAI_MAX_TOKENS', parameters('azureOpenAIMaxTokens'), 'AZURE_OPENAI_STOP_SEQUENCE', parameters('azureOpenAIStopSequence'), 'AZURE_OPENAI_SYSTEM_MESSAGE', parameters('azureOpenAISystemMessage'), 'AZURE_OPENAI_API_VERSION', parameters('azureOpenAIApiVersion'), 'AZURE_OPENAI_STREAM', parameters('azureOpenAIStream'), 'AZURE_OPENAI_EMBEDDING_MODEL', parameters('azureOpenAIEmbeddingModel'), 'AZURE_OPENAI_EMBEDDING_MODEL_NAME', parameters('azureOpenAIEmbeddingModelName'), 'AZURE_OPENAI_EMBEDDING_MODEL_VERSION', parameters('azureOpenAIEmbeddingModelVersion'), 'AZURE_SPEECH_SERVICE_NAME', variables('speechServiceName'), 'AZURE_SPEECH_SERVICE_REGION', parameters('location'), 'AZURE_SPEECH_RECOGNIZER_LANGUAGES', parameters('recognizedLanguages'), 'AZURE_SPEECH_REGION_ENDPOINT', reference('speechService').outputs.endpoint.value, 'USE_ADVANCED_IMAGE_PROCESSING', if(parameters('useAdvancedImageProcessing'), 'true', 'false'), 'ADVANCED_IMAGE_PROCESSING_MAX_IMAGES', string(parameters('advancedImageProcessingMaxImages')), 'ORCHESTRATION_STRATEGY', parameters('orchestrationStrategy'), 'CONVERSATION_FLOW', parameters('conversationFlow'), 'LOGLEVEL', parameters('logLevel'), 'PACKAGE_LOGGING_LEVEL', 'WARNING', 'AZURE_LOGGING_PACKAGES', '', 'DATABASE_TYPE', parameters('databaseType'), 'OPEN_AI_FUNCTIONS_SYSTEM_PROMPT', variables('openAIFunctionsSystemPrompt'), 'SEMANTIC_KERNEL_SYSTEM_PROMPT', variables('semanticKernelSystemPrompt'), 'MANAGED_IDENTITY_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'MANAGED_IDENTITY_RESOURCE_ID', reference('managedIdentityModule').outputs.resourceId.value, 'AZURE_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'APP_ENV', parameters('appEnvironment'), 'AZURE_SEARCH_DIMENSIONS', parameters('azureSearchDimensions')), if(equals(parameters('databaseType'), 'CosmosDB'), createObject('AZURE_COSMOSDB_ACCOUNT_NAME', variables('azureCosmosDBAccountName'), 'AZURE_COSMOSDB_DATABASE_NAME', variables('cosmosDbName'), 'AZURE_COSMOSDB_CONVERSATIONS_CONTAINER_NAME', variables('cosmosDbContainerName'), 'AZURE_COSMOSDB_ENABLE_FEEDBACK', 'true', 'AZURE_SEARCH_USE_SEMANTIC_SEARCH', if(parameters('azureSearchUseSemanticSearch'), 'true', 'false'), 'AZURE_SEARCH_SERVICE', format('https://{0}.search.windows.net', variables('azureAISearchName')), 'AZURE_SEARCH_INDEX', variables('azureSearchIndex'), 'AZURE_SEARCH_CONVERSATIONS_LOG_INDEX', parameters('azureSearchConversationLogIndex'), 'AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG', parameters('azureSearchSemanticSearchConfig'), 'AZURE_SEARCH_INDEX_IS_PRECHUNKED', parameters('azureSearchIndexIsPrechunked'), 'AZURE_SEARCH_TOP_K', parameters('azureSearchTopK'), 'AZURE_SEARCH_ENABLE_IN_DOMAIN', parameters('azureSearchEnableInDomain'), 'AZURE_SEARCH_FILENAME_COLUMN', parameters('azureSearchFilenameColumn'), 'AZURE_SEARCH_FILTER', parameters('azureSearchFilter'), 'AZURE_SEARCH_FIELDS_ID', parameters('azureSearchFieldId'), 'AZURE_SEARCH_CONTENT_COLUMN', parameters('azureSearchContentColumn'), 'AZURE_SEARCH_CONTENT_VECTOR_COLUMN', parameters('azureSearchVectorColumn'), 'AZURE_SEARCH_TITLE_COLUMN', parameters('azureSearchTitleColumn'), 'AZURE_SEARCH_FIELDS_METADATA', parameters('azureSearchFieldsMetadata'), 'AZURE_SEARCH_SOURCE_COLUMN', parameters('azureSearchSourceColumn'), 'AZURE_SEARCH_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchTextColumn'), ''), 'AZURE_SEARCH_LAYOUT_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchLayoutTextColumn'), ''), 'AZURE_SEARCH_CHUNK_COLUMN', parameters('azureSearchChunkColumn'), 'AZURE_SEARCH_OFFSET_COLUMN', parameters('azureSearchOffsetColumn'), 'AZURE_SEARCH_URL_COLUMN', parameters('azureSearchUrlColumn'), 'AZURE_SEARCH_USE_INTEGRATED_VECTORIZATION', if(parameters('azureSearchUseIntegratedVectorization'), 'true', 'false')), if(equals(parameters('databaseType'), 'PostgreSQL'), createObject('AZURE_POSTGRESQL_HOST_NAME', variables('postgresDBFqdn'), 'AZURE_POSTGRESQL_DATABASE_NAME', variables('postgresDBName'), 'AZURE_POSTGRESQL_USER', reference('managedIdentityModule').outputs.name.value), createObject())))]" + "value": "[union(createObject('AZURE_BLOB_ACCOUNT_NAME', variables('storageAccountName'), 'AZURE_BLOB_CONTAINER_NAME', variables('blobContainerName'), 'AZURE_FORM_RECOGNIZER_ENDPOINT', format('https://{0}.cognitiveservices.azure.com/', variables('formRecognizerName')), 'AZURE_COMPUTER_VISION_ENDPOINT', if(parameters('useAdvancedImageProcessing'), format('https://{0}.cognitiveservices.azure.com/', variables('computerVisionName')), ''), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION', parameters('computerVisionVectorizeImageApiVersion'), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_MODEL_VERSION', parameters('computerVisionVectorizeImageModelVersion'), 'AZURE_CONTENT_SAFETY_ENDPOINT', format('https://{0}.cognitiveservices.azure.com/', variables('contentSafetyName')), 'AZURE_KEY_VAULT_ENDPOINT', format('https://{0}{1}/', variables('keyVaultName'), environment().suffixes.keyvaultDns), 'AZURE_OPENAI_RESOURCE', variables('azureOpenAIResourceName'), 'AZURE_OPENAI_MODEL', parameters('azureOpenAIModel'), 'AZURE_OPENAI_MODEL_NAME', parameters('azureOpenAIModelName'), 'AZURE_OPENAI_MODEL_VERSION', parameters('azureOpenAIModelVersion'), 'AZURE_OPENAI_TEMPERATURE', parameters('azureOpenAITemperature'), 'AZURE_OPENAI_TOP_P', parameters('azureOpenAITopP'), 'AZURE_OPENAI_MAX_TOKENS', parameters('azureOpenAIMaxTokens'), 'AZURE_OPENAI_STOP_SEQUENCE', parameters('azureOpenAIStopSequence'), 'AZURE_OPENAI_SYSTEM_MESSAGE', parameters('azureOpenAISystemMessage'), 'AZURE_OPENAI_API_VERSION', parameters('azureOpenAIApiVersion'), 'AZURE_OPENAI_STREAM', parameters('azureOpenAIStream'), 'AZURE_OPENAI_EMBEDDING_MODEL', parameters('azureOpenAIEmbeddingModel'), 'AZURE_OPENAI_EMBEDDING_MODEL_NAME', parameters('azureOpenAIEmbeddingModelName'), 'AZURE_OPENAI_EMBEDDING_MODEL_VERSION', parameters('azureOpenAIEmbeddingModelVersion'), 'AZURE_SPEECH_SERVICE_NAME', variables('speechServiceName'), 'AZURE_SPEECH_SERVICE_REGION', parameters('location'), 'AZURE_SPEECH_RECOGNIZER_LANGUAGES', parameters('recognizedLanguages'), 'AZURE_SPEECH_REGION_ENDPOINT', format('https://{0}.cognitiveservices.azure.com/', variables('speechServiceName')), 'USE_ADVANCED_IMAGE_PROCESSING', if(parameters('useAdvancedImageProcessing'), 'true', 'false'), 'ADVANCED_IMAGE_PROCESSING_MAX_IMAGES', string(parameters('advancedImageProcessingMaxImages')), 'ORCHESTRATION_STRATEGY', parameters('orchestrationStrategy'), 'CONVERSATION_FLOW', parameters('conversationFlow'), 'LOGLEVEL', parameters('logLevel'), 'PACKAGE_LOGGING_LEVEL', 'WARNING', 'AZURE_LOGGING_PACKAGES', '', 'DATABASE_TYPE', parameters('databaseType'), 'OPEN_AI_FUNCTIONS_SYSTEM_PROMPT', variables('openAIFunctionsSystemPrompt'), 'SEMANTIC_KERNEL_SYSTEM_PROMPT', variables('semanticKernelSystemPrompt'), 'MANAGED_IDENTITY_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'MANAGED_IDENTITY_RESOURCE_ID', reference('managedIdentityModule').outputs.resourceId.value, 'AZURE_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'APP_ENV', parameters('appEnvironment'), 'AZURE_SEARCH_DIMENSIONS', parameters('azureSearchDimensions'), 'APPLICATIONINSIGHTS_ENABLED', if(parameters('enableMonitoring'), 'true', 'false')), if(equals(parameters('databaseType'), 'CosmosDB'), createObject('AZURE_COSMOSDB_ACCOUNT_NAME', variables('azureCosmosDBAccountName'), 'AZURE_COSMOSDB_DATABASE_NAME', variables('cosmosDbName'), 'AZURE_COSMOSDB_CONVERSATIONS_CONTAINER_NAME', variables('cosmosDbContainerName'), 'AZURE_COSMOSDB_ENABLE_FEEDBACK', 'true', 'AZURE_SEARCH_USE_SEMANTIC_SEARCH', if(parameters('azureSearchUseSemanticSearch'), 'true', 'false'), 'AZURE_SEARCH_SERVICE', format('https://{0}.search.windows.net', variables('azureAISearchName')), 'AZURE_SEARCH_INDEX', variables('azureSearchIndex'), 'AZURE_SEARCH_CONVERSATIONS_LOG_INDEX', parameters('azureSearchConversationLogIndex'), 'AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG', parameters('azureSearchSemanticSearchConfig'), 'AZURE_SEARCH_INDEX_IS_PRECHUNKED', parameters('azureSearchIndexIsPrechunked'), 'AZURE_SEARCH_TOP_K', parameters('azureSearchTopK'), 'AZURE_SEARCH_ENABLE_IN_DOMAIN', parameters('azureSearchEnableInDomain'), 'AZURE_SEARCH_FILENAME_COLUMN', parameters('azureSearchFilenameColumn'), 'AZURE_SEARCH_FILTER', parameters('azureSearchFilter'), 'AZURE_SEARCH_FIELDS_ID', parameters('azureSearchFieldId'), 'AZURE_SEARCH_CONTENT_COLUMN', parameters('azureSearchContentColumn'), 'AZURE_SEARCH_CONTENT_VECTOR_COLUMN', parameters('azureSearchVectorColumn'), 'AZURE_SEARCH_TITLE_COLUMN', parameters('azureSearchTitleColumn'), 'AZURE_SEARCH_FIELDS_METADATA', parameters('azureSearchFieldsMetadata'), 'AZURE_SEARCH_SOURCE_COLUMN', parameters('azureSearchSourceColumn'), 'AZURE_SEARCH_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchTextColumn'), ''), 'AZURE_SEARCH_LAYOUT_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchLayoutTextColumn'), ''), 'AZURE_SEARCH_CHUNK_COLUMN', parameters('azureSearchChunkColumn'), 'AZURE_SEARCH_OFFSET_COLUMN', parameters('azureSearchOffsetColumn'), 'AZURE_SEARCH_URL_COLUMN', parameters('azureSearchUrlColumn'), 'AZURE_SEARCH_USE_INTEGRATED_VECTORIZATION', if(parameters('azureSearchUseIntegratedVectorization'), 'true', 'false')), if(equals(parameters('databaseType'), 'PostgreSQL'), createObject('AZURE_POSTGRESQL_HOST_NAME', variables('postgresDBFqdn'), 'AZURE_POSTGRESQL_DATABASE_NAME', variables('postgresDBName'), 'AZURE_POSTGRESQL_USER', reference('managedIdentityModule').outputs.name.value), createObject())))]" } }, "template": { @@ -33148,8 +33148,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "1927711833258231470" + "version": "0.41.2.15936", + "templateHash": "8532914521980205931" } }, "parameters": { @@ -33406,8 +33406,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "8635359147587854848" + "version": "0.41.2.15936", + "templateHash": "2173437779685294467" } }, "definitions": { @@ -34423,8 +34423,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "7209561163082212668" + "version": "0.41.2.15936", + "templateHash": "1185169597469996118" }, "name": "Site App Settings", "description": "This module deploys a Site App Setting." @@ -35397,13 +35397,8 @@ } }, "dependsOn": [ - "computerVision", - "contentsafety", - "formrecognizer", - "keyvault", "managedIdentityModule", "monitoring", - "speechService", "virtualNetwork", "webServerFarm" ] @@ -35440,7 +35435,7 @@ "value": "[reference('managedIdentityModule').outputs.resourceId.value]" }, "appSettings": { - "value": "[union(createObject('AZURE_BLOB_ACCOUNT_NAME', variables('storageAccountName'), 'AZURE_BLOB_CONTAINER_NAME', variables('blobContainerName'), 'AZURE_FORM_RECOGNIZER_ENDPOINT', reference('formrecognizer').outputs.endpoint.value, 'AZURE_COMPUTER_VISION_ENDPOINT', if(parameters('useAdvancedImageProcessing'), reference('computerVision').outputs.endpoint.value, ''), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION', parameters('computerVisionVectorizeImageApiVersion'), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_MODEL_VERSION', parameters('computerVisionVectorizeImageModelVersion'), 'AZURE_CONTENT_SAFETY_ENDPOINT', reference('contentsafety').outputs.endpoint.value, 'AZURE_KEY_VAULT_ENDPOINT', reference('keyvault').outputs.uri.value, 'AZURE_OPENAI_RESOURCE', variables('azureOpenAIResourceName'), 'AZURE_OPENAI_MODEL', parameters('azureOpenAIModel'), 'AZURE_OPENAI_MODEL_NAME', parameters('azureOpenAIModelName'), 'AZURE_OPENAI_MODEL_VERSION', parameters('azureOpenAIModelVersion'), 'AZURE_OPENAI_TEMPERATURE', parameters('azureOpenAITemperature'), 'AZURE_OPENAI_TOP_P', parameters('azureOpenAITopP'), 'AZURE_OPENAI_MAX_TOKENS', parameters('azureOpenAIMaxTokens'), 'AZURE_OPENAI_STOP_SEQUENCE', parameters('azureOpenAIStopSequence'), 'AZURE_OPENAI_SYSTEM_MESSAGE', parameters('azureOpenAISystemMessage'), 'AZURE_OPENAI_API_VERSION', parameters('azureOpenAIApiVersion'), 'AZURE_OPENAI_STREAM', parameters('azureOpenAIStream'), 'AZURE_OPENAI_EMBEDDING_MODEL', parameters('azureOpenAIEmbeddingModel'), 'AZURE_OPENAI_EMBEDDING_MODEL_NAME', parameters('azureOpenAIEmbeddingModelName'), 'AZURE_OPENAI_EMBEDDING_MODEL_VERSION', parameters('azureOpenAIEmbeddingModelVersion'), 'USE_ADVANCED_IMAGE_PROCESSING', if(parameters('useAdvancedImageProcessing'), 'true', 'false'), 'BACKEND_URL', format('https://{0}.azurewebsites.net', if(equals(parameters('hostingModel'), 'container'), format('{0}-docker', variables('functionName')), variables('functionName'))), 'DOCUMENT_PROCESSING_QUEUE_NAME', variables('queueName'), 'FUNCTION_KEY', 'FUNCTION-KEY', 'ORCHESTRATION_STRATEGY', parameters('orchestrationStrategy'), 'CONVERSATION_FLOW', parameters('conversationFlow'), 'LOGLEVEL', parameters('logLevel'), 'PACKAGE_LOGGING_LEVEL', 'WARNING', 'AZURE_LOGGING_PACKAGES', '', 'DATABASE_TYPE', parameters('databaseType'), 'USE_KEY_VAULT', 'true', 'MANAGED_IDENTITY_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'MANAGED_IDENTITY_RESOURCE_ID', reference('managedIdentityModule').outputs.resourceId.value, 'APP_ENV', parameters('appEnvironment'), 'AZURE_SEARCH_DIMENSIONS', parameters('azureSearchDimensions')), if(equals(parameters('databaseType'), 'CosmosDB'), createObject('AZURE_SEARCH_SERVICE', format('https://{0}.search.windows.net', variables('azureAISearchName')), 'AZURE_SEARCH_INDEX', variables('azureSearchIndex'), 'AZURE_SEARCH_USE_SEMANTIC_SEARCH', if(parameters('azureSearchUseSemanticSearch'), 'true', 'false'), 'AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG', parameters('azureSearchSemanticSearchConfig'), 'AZURE_SEARCH_INDEX_IS_PRECHUNKED', parameters('azureSearchIndexIsPrechunked'), 'AZURE_SEARCH_TOP_K', parameters('azureSearchTopK'), 'AZURE_SEARCH_ENABLE_IN_DOMAIN', parameters('azureSearchEnableInDomain'), 'AZURE_SEARCH_FILENAME_COLUMN', parameters('azureSearchFilenameColumn'), 'AZURE_SEARCH_FILTER', parameters('azureSearchFilter'), 'AZURE_SEARCH_FIELDS_ID', parameters('azureSearchFieldId'), 'AZURE_SEARCH_CONTENT_COLUMN', parameters('azureSearchContentColumn'), 'AZURE_SEARCH_CONTENT_VECTOR_COLUMN', parameters('azureSearchVectorColumn'), 'AZURE_SEARCH_TITLE_COLUMN', parameters('azureSearchTitleColumn'), 'AZURE_SEARCH_FIELDS_METADATA', parameters('azureSearchFieldsMetadata'), 'AZURE_SEARCH_SOURCE_COLUMN', parameters('azureSearchSourceColumn'), 'AZURE_SEARCH_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchTextColumn'), ''), 'AZURE_SEARCH_LAYOUT_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchLayoutTextColumn'), ''), 'AZURE_SEARCH_CHUNK_COLUMN', parameters('azureSearchChunkColumn'), 'AZURE_SEARCH_OFFSET_COLUMN', parameters('azureSearchOffsetColumn'), 'AZURE_SEARCH_URL_COLUMN', parameters('azureSearchUrlColumn'), 'AZURE_SEARCH_DATASOURCE_NAME', variables('azureSearchDatasource'), 'AZURE_SEARCH_INDEXER_NAME', variables('azureSearchIndexer'), 'AZURE_SEARCH_USE_INTEGRATED_VECTORIZATION', if(parameters('azureSearchUseIntegratedVectorization'), 'true', 'false')), if(equals(parameters('databaseType'), 'PostgreSQL'), createObject('AZURE_POSTGRESQL_HOST_NAME', variables('postgresDBFqdn'), 'AZURE_POSTGRESQL_DATABASE_NAME', variables('postgresDBName'), 'AZURE_POSTGRESQL_USER', reference('managedIdentityModule').outputs.name.value), createObject())))]" + "value": "[union(createObject('AZURE_BLOB_ACCOUNT_NAME', variables('storageAccountName'), 'AZURE_BLOB_CONTAINER_NAME', variables('blobContainerName'), 'AZURE_FORM_RECOGNIZER_ENDPOINT', format('https://{0}.cognitiveservices.azure.com/', variables('formRecognizerName')), 'AZURE_COMPUTER_VISION_ENDPOINT', if(parameters('useAdvancedImageProcessing'), format('https://{0}.cognitiveservices.azure.com/', variables('computerVisionName')), ''), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION', parameters('computerVisionVectorizeImageApiVersion'), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_MODEL_VERSION', parameters('computerVisionVectorizeImageModelVersion'), 'AZURE_CONTENT_SAFETY_ENDPOINT', format('https://{0}.cognitiveservices.azure.com/', variables('contentSafetyName')), 'AZURE_KEY_VAULT_ENDPOINT', format('https://{0}{1}/', variables('keyVaultName'), environment().suffixes.keyvaultDns), 'AZURE_OPENAI_RESOURCE', variables('azureOpenAIResourceName'), 'AZURE_OPENAI_MODEL', parameters('azureOpenAIModel'), 'AZURE_OPENAI_MODEL_NAME', parameters('azureOpenAIModelName'), 'AZURE_OPENAI_MODEL_VERSION', parameters('azureOpenAIModelVersion'), 'AZURE_OPENAI_TEMPERATURE', parameters('azureOpenAITemperature'), 'AZURE_OPENAI_TOP_P', parameters('azureOpenAITopP'), 'AZURE_OPENAI_MAX_TOKENS', parameters('azureOpenAIMaxTokens'), 'AZURE_OPENAI_STOP_SEQUENCE', parameters('azureOpenAIStopSequence'), 'AZURE_OPENAI_SYSTEM_MESSAGE', parameters('azureOpenAISystemMessage'), 'AZURE_OPENAI_API_VERSION', parameters('azureOpenAIApiVersion'), 'AZURE_OPENAI_STREAM', parameters('azureOpenAIStream'), 'AZURE_OPENAI_EMBEDDING_MODEL', parameters('azureOpenAIEmbeddingModel'), 'AZURE_OPENAI_EMBEDDING_MODEL_NAME', parameters('azureOpenAIEmbeddingModelName'), 'AZURE_OPENAI_EMBEDDING_MODEL_VERSION', parameters('azureOpenAIEmbeddingModelVersion'), 'USE_ADVANCED_IMAGE_PROCESSING', if(parameters('useAdvancedImageProcessing'), 'true', 'false'), 'BACKEND_URL', format('https://{0}.azurewebsites.net', if(equals(parameters('hostingModel'), 'container'), format('{0}-docker', variables('functionName')), variables('functionName'))), 'DOCUMENT_PROCESSING_QUEUE_NAME', variables('queueName'), 'FUNCTION_KEY', 'FUNCTION-KEY', 'ORCHESTRATION_STRATEGY', parameters('orchestrationStrategy'), 'CONVERSATION_FLOW', parameters('conversationFlow'), 'LOGLEVEL', parameters('logLevel'), 'PACKAGE_LOGGING_LEVEL', 'WARNING', 'AZURE_LOGGING_PACKAGES', '', 'DATABASE_TYPE', parameters('databaseType'), 'USE_KEY_VAULT', 'true', 'MANAGED_IDENTITY_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'MANAGED_IDENTITY_RESOURCE_ID', reference('managedIdentityModule').outputs.resourceId.value, 'APP_ENV', parameters('appEnvironment'), 'AZURE_SEARCH_DIMENSIONS', parameters('azureSearchDimensions'), 'APPLICATIONINSIGHTS_ENABLED', if(parameters('enableMonitoring'), 'true', 'false')), if(equals(parameters('databaseType'), 'CosmosDB'), createObject('AZURE_SEARCH_SERVICE', format('https://{0}.search.windows.net', variables('azureAISearchName')), 'AZURE_SEARCH_INDEX', variables('azureSearchIndex'), 'AZURE_SEARCH_USE_SEMANTIC_SEARCH', if(parameters('azureSearchUseSemanticSearch'), 'true', 'false'), 'AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG', parameters('azureSearchSemanticSearchConfig'), 'AZURE_SEARCH_INDEX_IS_PRECHUNKED', parameters('azureSearchIndexIsPrechunked'), 'AZURE_SEARCH_TOP_K', parameters('azureSearchTopK'), 'AZURE_SEARCH_ENABLE_IN_DOMAIN', parameters('azureSearchEnableInDomain'), 'AZURE_SEARCH_FILENAME_COLUMN', parameters('azureSearchFilenameColumn'), 'AZURE_SEARCH_FILTER', parameters('azureSearchFilter'), 'AZURE_SEARCH_FIELDS_ID', parameters('azureSearchFieldId'), 'AZURE_SEARCH_CONTENT_COLUMN', parameters('azureSearchContentColumn'), 'AZURE_SEARCH_CONTENT_VECTOR_COLUMN', parameters('azureSearchVectorColumn'), 'AZURE_SEARCH_TITLE_COLUMN', parameters('azureSearchTitleColumn'), 'AZURE_SEARCH_FIELDS_METADATA', parameters('azureSearchFieldsMetadata'), 'AZURE_SEARCH_SOURCE_COLUMN', parameters('azureSearchSourceColumn'), 'AZURE_SEARCH_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchTextColumn'), ''), 'AZURE_SEARCH_LAYOUT_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchLayoutTextColumn'), ''), 'AZURE_SEARCH_CHUNK_COLUMN', parameters('azureSearchChunkColumn'), 'AZURE_SEARCH_OFFSET_COLUMN', parameters('azureSearchOffsetColumn'), 'AZURE_SEARCH_URL_COLUMN', parameters('azureSearchUrlColumn'), 'AZURE_SEARCH_DATASOURCE_NAME', variables('azureSearchDatasource'), 'AZURE_SEARCH_INDEXER_NAME', variables('azureSearchIndexer'), 'AZURE_SEARCH_USE_INTEGRATED_VECTORIZATION', if(parameters('azureSearchUseIntegratedVectorization'), 'true', 'false')), if(equals(parameters('databaseType'), 'PostgreSQL'), createObject('AZURE_POSTGRESQL_HOST_NAME', variables('postgresDBFqdn'), 'AZURE_POSTGRESQL_DATABASE_NAME', variables('postgresDBName'), 'AZURE_POSTGRESQL_USER', reference('managedIdentityModule').outputs.name.value), createObject())))]" }, "applicationInsightsName": "[if(parameters('enableMonitoring'), createObject('value', reference('monitoring').outputs.applicationInsightsName.value), createObject('value', ''))]", "diagnosticSettings": "[if(parameters('enableMonitoring'), createObject('value', createArray(createObject('workspaceResourceId', reference('monitoring').outputs.logAnalyticsWorkspaceId.value))), createObject('value', createArray()))]", @@ -35458,8 +35453,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "12578972352156070625" + "version": "0.41.2.15936", + "templateHash": "12347074396707017406" } }, "parameters": { @@ -35716,8 +35711,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "8635359147587854848" + "version": "0.41.2.15936", + "templateHash": "2173437779685294467" } }, "definitions": { @@ -36733,8 +36728,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "7209561163082212668" + "version": "0.41.2.15936", + "templateHash": "1185169597469996118" }, "name": "Site App Settings", "description": "This module deploys a Site App Setting." @@ -37707,10 +37702,6 @@ } }, "dependsOn": [ - "computerVision", - "contentsafety", - "formrecognizer", - "keyvault", "managedIdentityModule", "monitoring", "virtualNetwork", @@ -37762,7 +37753,7 @@ "value": "Enabled" }, "appSettings": { - "value": "[union(createObject('AZURE_BLOB_ACCOUNT_NAME', variables('storageAccountName'), 'AZURE_BLOB_CONTAINER_NAME', variables('blobContainerName'), 'AZURE_FORM_RECOGNIZER_ENDPOINT', reference('formrecognizer').outputs.endpoint.value, 'AZURE_COMPUTER_VISION_ENDPOINT', if(parameters('useAdvancedImageProcessing'), reference('computerVision').outputs.endpoint.value, ''), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION', parameters('computerVisionVectorizeImageApiVersion'), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_MODEL_VERSION', parameters('computerVisionVectorizeImageModelVersion'), 'AZURE_CONTENT_SAFETY_ENDPOINT', reference('contentsafety').outputs.endpoint.value, 'AZURE_KEY_VAULT_ENDPOINT', reference('keyvault').outputs.uri.value, 'AZURE_OPENAI_MODEL', parameters('azureOpenAIModel'), 'AZURE_OPENAI_MODEL_NAME', parameters('azureOpenAIModelName'), 'AZURE_OPENAI_MODEL_VERSION', parameters('azureOpenAIModelVersion'), 'AZURE_OPENAI_EMBEDDING_MODEL', parameters('azureOpenAIEmbeddingModel'), 'AZURE_OPENAI_EMBEDDING_MODEL_NAME', parameters('azureOpenAIEmbeddingModelName'), 'AZURE_OPENAI_EMBEDDING_MODEL_VERSION', parameters('azureOpenAIEmbeddingModelVersion'), 'AZURE_OPENAI_RESOURCE', variables('azureOpenAIResourceName'), 'AZURE_OPENAI_API_VERSION', parameters('azureOpenAIApiVersion'), 'USE_ADVANCED_IMAGE_PROCESSING', if(parameters('useAdvancedImageProcessing'), 'true', 'false'), 'DOCUMENT_PROCESSING_QUEUE_NAME', variables('queueName'), 'ORCHESTRATION_STRATEGY', parameters('orchestrationStrategy'), 'LOGLEVEL', parameters('logLevel'), 'PACKAGE_LOGGING_LEVEL', 'WARNING', 'AZURE_LOGGING_PACKAGES', '', 'AZURE_OPENAI_SYSTEM_MESSAGE', parameters('azureOpenAISystemMessage'), 'OPEN_AI_FUNCTIONS_SYSTEM_PROMPT', variables('openAIFunctionsSystemPrompt'), 'SEMANTIC_KERNEL_SYSTEM_PROMPT', variables('semanticKernelSystemPrompt'), 'DATABASE_TYPE', parameters('databaseType'), 'MANAGED_IDENTITY_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'MANAGED_IDENTITY_RESOURCE_ID', reference('managedIdentityModule').outputs.resourceId.value, 'AZURE_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'APP_ENV', parameters('appEnvironment'), 'BACKEND_URL', variables('backendUrl'), 'AZURE_SEARCH_DIMENSIONS', parameters('azureSearchDimensions')), if(equals(parameters('databaseType'), 'CosmosDB'), createObject('AZURE_SEARCH_INDEX', variables('azureSearchIndex'), 'AZURE_SEARCH_SERVICE', format('https://{0}.search.windows.net', variables('azureAISearchName')), 'AZURE_SEARCH_DATASOURCE_NAME', variables('azureSearchDatasource'), 'AZURE_SEARCH_INDEXER_NAME', variables('azureSearchIndexer'), 'AZURE_SEARCH_USE_INTEGRATED_VECTORIZATION', if(parameters('azureSearchUseIntegratedVectorization'), 'true', 'false'), 'AZURE_SEARCH_FIELDS_ID', parameters('azureSearchFieldId'), 'AZURE_SEARCH_CONTENT_COLUMN', parameters('azureSearchContentColumn'), 'AZURE_SEARCH_CONTENT_VECTOR_COLUMN', parameters('azureSearchVectorColumn'), 'AZURE_SEARCH_TITLE_COLUMN', parameters('azureSearchTitleColumn'), 'AZURE_SEARCH_FIELDS_METADATA', parameters('azureSearchFieldsMetadata'), 'AZURE_SEARCH_SOURCE_COLUMN', parameters('azureSearchSourceColumn'), 'AZURE_SEARCH_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchTextColumn'), ''), 'AZURE_SEARCH_LAYOUT_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchLayoutTextColumn'), ''), 'AZURE_SEARCH_CHUNK_COLUMN', parameters('azureSearchChunkColumn'), 'AZURE_SEARCH_OFFSET_COLUMN', parameters('azureSearchOffsetColumn'), 'AZURE_SEARCH_TOP_K', parameters('azureSearchTopK')), if(equals(parameters('databaseType'), 'PostgreSQL'), createObject('AZURE_POSTGRESQL_HOST_NAME', variables('postgresDBFqdn'), 'AZURE_POSTGRESQL_DATABASE_NAME', variables('postgresDBName'), 'AZURE_POSTGRESQL_USER', reference('managedIdentityModule').outputs.name.value), createObject())))]" + "value": "[union(createObject('AZURE_BLOB_ACCOUNT_NAME', variables('storageAccountName'), 'AZURE_BLOB_CONTAINER_NAME', variables('blobContainerName'), 'AZURE_FORM_RECOGNIZER_ENDPOINT', format('https://{0}.cognitiveservices.azure.com/', variables('formRecognizerName')), 'AZURE_COMPUTER_VISION_ENDPOINT', if(parameters('useAdvancedImageProcessing'), format('https://{0}.cognitiveservices.azure.com/', variables('computerVisionName')), ''), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION', parameters('computerVisionVectorizeImageApiVersion'), 'AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_MODEL_VERSION', parameters('computerVisionVectorizeImageModelVersion'), 'AZURE_CONTENT_SAFETY_ENDPOINT', format('https://{0}.cognitiveservices.azure.com/', variables('contentSafetyName')), 'AZURE_KEY_VAULT_ENDPOINT', format('https://{0}{1}/', variables('keyVaultName'), environment().suffixes.keyvaultDns), 'AZURE_OPENAI_MODEL', parameters('azureOpenAIModel'), 'AZURE_OPENAI_MODEL_NAME', parameters('azureOpenAIModelName'), 'AZURE_OPENAI_MODEL_VERSION', parameters('azureOpenAIModelVersion'), 'AZURE_OPENAI_EMBEDDING_MODEL', parameters('azureOpenAIEmbeddingModel'), 'AZURE_OPENAI_EMBEDDING_MODEL_NAME', parameters('azureOpenAIEmbeddingModelName'), 'AZURE_OPENAI_EMBEDDING_MODEL_VERSION', parameters('azureOpenAIEmbeddingModelVersion'), 'AZURE_OPENAI_RESOURCE', variables('azureOpenAIResourceName'), 'AZURE_OPENAI_API_VERSION', parameters('azureOpenAIApiVersion'), 'USE_ADVANCED_IMAGE_PROCESSING', if(parameters('useAdvancedImageProcessing'), 'true', 'false'), 'DOCUMENT_PROCESSING_QUEUE_NAME', variables('queueName'), 'ORCHESTRATION_STRATEGY', parameters('orchestrationStrategy'), 'LOGLEVEL', parameters('logLevel'), 'PACKAGE_LOGGING_LEVEL', 'WARNING', 'AZURE_LOGGING_PACKAGES', '', 'AZURE_OPENAI_SYSTEM_MESSAGE', parameters('azureOpenAISystemMessage'), 'OPEN_AI_FUNCTIONS_SYSTEM_PROMPT', variables('openAIFunctionsSystemPrompt'), 'SEMANTIC_KERNEL_SYSTEM_PROMPT', variables('semanticKernelSystemPrompt'), 'DATABASE_TYPE', parameters('databaseType'), 'MANAGED_IDENTITY_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'MANAGED_IDENTITY_RESOURCE_ID', reference('managedIdentityModule').outputs.resourceId.value, 'AZURE_CLIENT_ID', reference('managedIdentityModule').outputs.clientId.value, 'APP_ENV', parameters('appEnvironment'), 'BACKEND_URL', variables('backendUrl'), 'AZURE_SEARCH_DIMENSIONS', parameters('azureSearchDimensions'), 'APPLICATIONINSIGHTS_ENABLED', if(parameters('enableMonitoring'), 'true', 'false')), if(equals(parameters('databaseType'), 'CosmosDB'), createObject('AZURE_SEARCH_INDEX', variables('azureSearchIndex'), 'AZURE_SEARCH_SERVICE', format('https://{0}.search.windows.net', variables('azureAISearchName')), 'AZURE_SEARCH_DATASOURCE_NAME', variables('azureSearchDatasource'), 'AZURE_SEARCH_INDEXER_NAME', variables('azureSearchIndexer'), 'AZURE_SEARCH_USE_INTEGRATED_VECTORIZATION', if(parameters('azureSearchUseIntegratedVectorization'), 'true', 'false'), 'AZURE_SEARCH_FIELDS_ID', parameters('azureSearchFieldId'), 'AZURE_SEARCH_CONTENT_COLUMN', parameters('azureSearchContentColumn'), 'AZURE_SEARCH_CONTENT_VECTOR_COLUMN', parameters('azureSearchVectorColumn'), 'AZURE_SEARCH_TITLE_COLUMN', parameters('azureSearchTitleColumn'), 'AZURE_SEARCH_FIELDS_METADATA', parameters('azureSearchFieldsMetadata'), 'AZURE_SEARCH_SOURCE_COLUMN', parameters('azureSearchSourceColumn'), 'AZURE_SEARCH_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchTextColumn'), ''), 'AZURE_SEARCH_LAYOUT_TEXT_COLUMN', if(parameters('azureSearchUseIntegratedVectorization'), parameters('azureSearchLayoutTextColumn'), ''), 'AZURE_SEARCH_CHUNK_COLUMN', parameters('azureSearchChunkColumn'), 'AZURE_SEARCH_OFFSET_COLUMN', parameters('azureSearchOffsetColumn'), 'AZURE_SEARCH_TOP_K', parameters('azureSearchTopK')), if(equals(parameters('databaseType'), 'PostgreSQL'), createObject('AZURE_POSTGRESQL_HOST_NAME', variables('postgresDBFqdn'), 'AZURE_POSTGRESQL_DATABASE_NAME', variables('postgresDBName'), 'AZURE_POSTGRESQL_USER', reference('managedIdentityModule').outputs.name.value), createObject())))]" } }, "template": { @@ -37772,8 +37763,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "579857106859534555" + "version": "0.41.2.15936", + "templateHash": "18272396686912776072" } }, "parameters": { @@ -38013,8 +38004,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "17498839439506952033" + "version": "0.41.2.15936", + "templateHash": "3443210178091027572" } }, "parameters": { @@ -38379,8 +38370,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "8635359147587854848" + "version": "0.41.2.15936", + "templateHash": "2173437779685294467" } }, "definitions": { @@ -39396,8 +39387,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "7209561163082212668" + "version": "0.41.2.15936", + "templateHash": "1185169597469996118" }, "name": "Site App Settings", "description": "This module deploys a Site App Setting." @@ -40394,10 +40385,6 @@ } }, "dependsOn": [ - "computerVision", - "contentsafety", - "formrecognizer", - "keyvault", "managedIdentityModule", "monitoring", "storage", @@ -40456,8 +40443,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "13340959005376551223" + "version": "0.41.2.15936", + "templateHash": "2891545763226126731" }, "name": "monitoring-solution", "description": "AVM WAF-compliant monitoring solution that integrates Application Insights with Log Analytics for centralized telemetry, diagnostics, and observability." @@ -43734,8 +43721,7 @@ "flowType": { "value": "Bluefield" }, - "workspaceResourceId": "[if(empty(if(empty(parameters('existingLogAnalyticsWorkspaceId')), reference('avmWorkspace').outputs.resourceId.value, parameters('existingLogAnalyticsWorkspaceId'))), createObject('value', ''), if(empty(parameters('existingLogAnalyticsWorkspaceId')), createObject('value', reference('avmWorkspace').outputs.resourceId.value), createObject('value', parameters('existingLogAnalyticsWorkspaceId'))))]", - "diagnosticSettings": "[if(empty(if(empty(parameters('existingLogAnalyticsWorkspaceId')), reference('avmWorkspace').outputs.resourceId.value, parameters('existingLogAnalyticsWorkspaceId'))), createObject('value', null()), createObject('value', createArray(createObject('workspaceResourceId', if(empty(parameters('existingLogAnalyticsWorkspaceId')), reference('avmWorkspace').outputs.resourceId.value, parameters('existingLogAnalyticsWorkspaceId'))))))]" + "workspaceResourceId": "[if(empty(if(empty(parameters('existingLogAnalyticsWorkspaceId')), reference('avmWorkspace').outputs.resourceId.value, parameters('existingLogAnalyticsWorkspaceId'))), createObject('value', ''), if(empty(parameters('existingLogAnalyticsWorkspaceId')), createObject('value', reference('avmWorkspace').outputs.resourceId.value), createObject('value', parameters('existingLogAnalyticsWorkspaceId'))))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -46084,8 +46070,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "11466056601858560902" + "version": "0.41.2.15936", + "templateHash": "9897399857943770193" } }, "parameters": { @@ -46303,8 +46289,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "663091920696574433" + "version": "0.41.2.15936", + "templateHash": "1086305767743367425" }, "name": "Cognitive Services", "description": "This module deploys a Cognitive Service." @@ -48634,7 +48620,7 @@ } }, "dependsOn": [ - "avmPrivateDnsZones", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]", "managedIdentityModule", "monitoring", "virtualNetwork" @@ -48688,8 +48674,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "11466056601858560902" + "version": "0.41.2.15936", + "templateHash": "9897399857943770193" } }, "parameters": { @@ -48907,8 +48893,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "663091920696574433" + "version": "0.41.2.15936", + "templateHash": "1086305767743367425" }, "name": "Cognitive Services", "description": "This module deploys a Cognitive Service." @@ -51238,7 +51224,7 @@ } }, "dependsOn": [ - "avmPrivateDnsZones", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]", "managedIdentityModule", "monitoring", "virtualNetwork" @@ -51348,8 +51334,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "3041722222428541576" + "version": "0.41.2.15936", + "templateHash": "17411815865895438280" }, "name": "Storage Accounts", "description": "This module deploys a Storage Account." @@ -53390,8 +53376,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "10760162124613925487" + "version": "0.41.2.15936", + "templateHash": "1615241847605833494" }, "name": "Storage Account blob Services", "description": "This module deploys a Storage Account Blob Service." @@ -53855,8 +53841,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "15247673480492849622" + "version": "0.41.2.15936", + "templateHash": "2504838016669447838" }, "name": "Storage Account Blob Containers", "description": "This module deploys a Storage Account Blob Container." @@ -54085,8 +54071,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "13860544937205162319" + "version": "0.41.2.15936", + "templateHash": "8672616740318557899" }, "name": "Storage Account Queue Services", "description": "This module deploys a Storage Account Queue Service." @@ -54400,8 +54386,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "9325202735636472943" + "version": "0.41.2.15936", + "templateHash": "14546567088712421783" }, "name": "Storage Account Queues", "description": "This module deploys a Storage Account Queue." @@ -54525,8 +54511,8 @@ }, "dependsOn": [ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageQueue)]", - "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]", "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageFile)]", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]", "managedIdentityModule", "virtualNetwork" ] @@ -54580,8 +54566,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "13108381981388611376" + "version": "0.41.2.15936", + "templateHash": "8897699566179561823" } }, "parameters": { @@ -54663,8 +54649,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "7477398503251150415" + "version": "0.41.2.15936", + "templateHash": "2448405259058465422" }, "name": "workbook", "description": "AVM WAF-compliant Workbook deployment using Microsoft.Insights resource type. Ensures governance, observability, tagging, and consistency with other monitoring resources." @@ -56022,8 +56008,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "9481064221465229369" + "version": "0.41.2.15936", + "templateHash": "7914850545661773922" } }, "parameters": { diff --git a/infra/modules/virtualNetwork.bicep b/infra/modules/virtualNetwork.bicep index 86216f820..1359e0890 100644 --- a/infra/modules/virtualNetwork.bicep +++ b/infra/modules/virtualNetwork.bicep @@ -208,7 +208,7 @@ param resourceSuffix string // using AVM Network Security Group module // https://github.com/Azure/bicep-registry-modules/tree/main/avm/res/network/network-security-group -@batchSize(1) +@batchSize(4) module nsgs 'br/public:avm/res/network/network-security-group:0.5.1' = [ for (subnet, i) in subnets: if (!empty(subnet.?networkSecurityGroup)) { name: take('avm.res.network.network-security-group.${subnet.?networkSecurityGroup.name}.${resourceSuffix}', 64) diff --git a/scripts/post_deployment_setup.ps1 b/scripts/post_deployment_setup.ps1 index 3c064636c..015e5b770 100644 --- a/scripts/post_deployment_setup.ps1 +++ b/scripts/post_deployment_setup.ps1 @@ -43,20 +43,22 @@ $currentIdentityOid = $null $currentIdentityDisplay = $null $principalType = "User" -# Try signed-in user first -$currentIdentityOid = az ad signed-in-user show --query "id" -o tsv 2>$null -if ($currentIdentityOid) { +# Try signed-in user first (single API call to get both id and userPrincipalName) +$userInfo = az ad signed-in-user show 2>$null | ConvertFrom-Json +if ($userInfo) { $identityType = "user" - $currentIdentityDisplay = az ad signed-in-user show --query "userPrincipalName" -o tsv 2>$null + $currentIdentityOid = $userInfo.id + $currentIdentityDisplay = $userInfo.userPrincipalName $principalType = "User" Write-Host "✓ Detected identity type: User ($currentIdentityDisplay)" } else { - # Fallback to service principal + # Fallback to service principal (single API call per resource) $spAppId = az account show --query "user.name" -o tsv 2>$null if ($spAppId -and $spAppId -ne "null") { - $currentIdentityOid = az ad sp show --id $spAppId --query "id" -o tsv 2>$null - $currentIdentityDisplay = az ad sp show --id $spAppId --query "displayName" -o tsv 2>$null - if ($currentIdentityOid) { + $spInfo = az ad sp show --id $spAppId 2>$null | ConvertFrom-Json + if ($spInfo) { + $currentIdentityOid = $spInfo.id + $currentIdentityDisplay = $spInfo.displayName $identityType = "servicePrincipal" $principalType = "ServicePrincipal" Write-Host "✓ Detected identity type: Service Principal ($currentIdentityDisplay, OID: $currentIdentityOid)" @@ -125,21 +127,21 @@ Write-Host "" Write-Host "--- Step 1: Set Function App Client Key ---" # Discover function app -$functionApps = az functionapp list --resource-group $ResourceGroupName --query "[].name" -o tsv 2>$null -if (-not $functionApps) { +$functionAppName = az functionapp list --resource-group $ResourceGroupName --query "[0].name" -o tsv 2>$null +if (-not $functionAppName) { Write-Warning "⚠ No function apps found in resource group '$ResourceGroupName'. Skipping function key setup." } else { - $functionAppName = ($functionApps -split "`n")[0].Trim() + $functionAppName = $functionAppName.Trim() Write-Host "✓ Discovered function app: $functionAppName" # Discover key vault - $keyVaults = az keyvault list --resource-group $ResourceGroupName --query "[].name" -o tsv 2>$null - if (-not $keyVaults) { + $keyVaultName = az keyvault list --resource-group $ResourceGroupName --query "[0].name" -o tsv 2>$null + if (-not $keyVaultName) { Write-Warning "⚠ No Key Vault found. Skipping function key setup." } else { - $keyVaultName = ($keyVaults -split "`n")[0].Trim() + $keyVaultName = $keyVaultName.Trim() Write-Host "✓ Discovered Key Vault: $keyVaultName" # Ensure the current identity has 'Key Vault Secrets User' role on the Key Vault @@ -226,12 +228,12 @@ else { Write-Host "" Write-Host "--- Step 2: Create PostgreSQL Tables ---" -$pgServers = az postgres flexible-server list --resource-group $ResourceGroupName --query "[].fullyQualifiedDomainName" -o tsv 2>$null -if (-not $pgServers) { +$serverFqdn = az postgres flexible-server list --resource-group $ResourceGroupName --query "[0].fullyQualifiedDomainName" -o tsv 2>$null +if (-not $serverFqdn) { Write-Host "No PostgreSQL Flexible Server found in resource group. Skipping table creation." } else { - $serverFqdn = ($pgServers -split "`n")[0].Trim() + $serverFqdn = $serverFqdn.Trim() $serverName = $serverFqdn.Split('.')[0] Write-Host "✓ Discovered PostgreSQL server: $serverName ($serverFqdn)" diff --git a/scripts/post_deployment_setup.sh b/scripts/post_deployment_setup.sh index fcd8c23a4..7b144c248 100644 --- a/scripts/post_deployment_setup.sh +++ b/scripts/post_deployment_setup.sh @@ -51,23 +51,27 @@ CURRENT_IDENTITY_OID="" CURRENT_IDENTITY_DISPLAY="" PRINCIPAL_TYPE="User" -# Try signed-in user first -CURRENT_IDENTITY_OID=$(az ad signed-in-user show --query "id" -o tsv 2>/dev/null || true) -if [ -n "$CURRENT_IDENTITY_OID" ]; then +# Try signed-in user first (single API call to get full JSON, then parse both fields) +USER_JSON=$(az ad signed-in-user show 2>/dev/null || true) +if [ -n "$USER_JSON" ]; then IDENTITY_TYPE="user" - CURRENT_IDENTITY_DISPLAY=$(az ad signed-in-user show --query "userPrincipalName" -o tsv 2>/dev/null || true) + CURRENT_IDENTITY_OID=$(echo "$USER_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])" 2>/dev/null || true) + CURRENT_IDENTITY_DISPLAY=$(echo "$USER_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['userPrincipalName'])" 2>/dev/null || true) PRINCIPAL_TYPE="User" echo "✓ Detected identity type: User (${CURRENT_IDENTITY_DISPLAY})" else - # Fallback to service principal — get the SP's app ID from the current account + # Fallback to service principal (single API call per resource) SP_APP_ID=$(az account show --query "user.name" -o tsv 2>/dev/null || true) if [ -n "$SP_APP_ID" ] && [ "$SP_APP_ID" != "null" ]; then - CURRENT_IDENTITY_OID=$(az ad sp show --id "$SP_APP_ID" --query "id" -o tsv 2>/dev/null || true) - CURRENT_IDENTITY_DISPLAY=$(az ad sp show --id "$SP_APP_ID" --query "displayName" -o tsv 2>/dev/null || true) - if [ -n "$CURRENT_IDENTITY_OID" ]; then - IDENTITY_TYPE="servicePrincipal" - PRINCIPAL_TYPE="ServicePrincipal" - echo "✓ Detected identity type: Service Principal (${CURRENT_IDENTITY_DISPLAY}, OID: ${CURRENT_IDENTITY_OID})" + SP_JSON=$(az ad sp show --id "$SP_APP_ID" 2>/dev/null || true) + if [ -n "$SP_JSON" ]; then + CURRENT_IDENTITY_OID=$(echo "$SP_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])" 2>/dev/null || true) + CURRENT_IDENTITY_DISPLAY=$(echo "$SP_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['displayName'])" 2>/dev/null || true) + if [ -n "$CURRENT_IDENTITY_OID" ]; then + IDENTITY_TYPE="servicePrincipal" + PRINCIPAL_TYPE="ServicePrincipal" + echo "✓ Detected identity type: Service Principal (${CURRENT_IDENTITY_DISPLAY}, OID: ${CURRENT_IDENTITY_OID})" + fi fi fi fi From 73dc98ac38787ca0fca26d36213ae16fc9352b67 Mon Sep 17 00:00:00 2001 From: Ajit Padhi Date: Thu, 23 Apr 2026 10:28:48 +0530 Subject: [PATCH 2/2] updated bicep --- code/scripts/package_frontend.ps1 | 2 +- code/scripts/package_frontend.sh | 2 +- docker/Frontend.Dockerfile | 2 ++ infra/main.bicep | 8 ------- infra/main.json | 6 +++--- scripts/post_deployment_setup.ps1 | 36 +++++++++++++++---------------- scripts/post_deployment_setup.sh | 26 ++++++++++------------ 7 files changed, 35 insertions(+), 47 deletions(-) diff --git a/code/scripts/package_frontend.ps1 b/code/scripts/package_frontend.ps1 index aaab72f72..82b82acdf 100644 --- a/code/scripts/package_frontend.ps1 +++ b/code/scripts/package_frontend.ps1 @@ -9,5 +9,5 @@ cp backend dist -r -Force # Node cd frontend -npm ci +npm install npm run build diff --git a/code/scripts/package_frontend.sh b/code/scripts/package_frontend.sh index 2b5a7b752..6b9c9893b 100644 --- a/code/scripts/package_frontend.sh +++ b/code/scripts/package_frontend.sh @@ -9,5 +9,5 @@ cp *.py dist cp -r backend dist cd frontend -npm ci +npm install npm run build diff --git a/docker/Frontend.Dockerfile b/docker/Frontend.Dockerfile index c80ec5d59..3cb03eb33 100644 --- a/docker/Frontend.Dockerfile +++ b/docker/Frontend.Dockerfile @@ -3,9 +3,11 @@ RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app WORKDIR /home/node/app COPY ./code/frontend/package*.json ./ USER node +# RUN npm install --force RUN npm ci COPY --chown=node:node ./code/frontend ./frontend WORKDIR /home/node/app/frontend +RUN npm install --save-dev @types/node @types/jest RUN npm run build FROM python:3.11.7-bookworm diff --git a/infra/main.bicep b/infra/main.bicep index eed9067ac..794cc7c55 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -989,7 +989,6 @@ module openai 'modules/core/ai/cognitiveservices.bicep' = { : [] ) } - // Implicit dependency on the specific DNS zone is established via the privateDnsZoneResourceId param reference } module computerVision 'modules/core/ai/cognitiveservices.bicep' = if (useAdvancedImageProcessing) { @@ -1030,7 +1029,6 @@ module computerVision 'modules/core/ai/cognitiveservices.bicep' = if (useAdvance : [] ) } - // Implicit dependency on the specific DNS zone is established via the privateDnsZoneResourceId param reference } // The Web socket from front end application connects to Speech service over a public internet and it does not work over a Private endpoint. @@ -1230,8 +1228,6 @@ module web 'modules/app/web.bicep' = { { AZURE_BLOB_ACCOUNT_NAME: storageAccountName AZURE_BLOB_CONTAINER_NAME: blobContainerName - // Endpoints constructed from resource names to avoid implicit dependencies on AI service modules, - // enabling parallel deployment of app services and AI services (customSubDomainName defaults to name) AZURE_FORM_RECOGNIZER_ENDPOINT: 'https://${formRecognizerName}.cognitiveservices.azure.com/' AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? 'https://${computerVisionName}.cognitiveservices.azure.com/' : '' AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION: computerVisionVectorizeImageApiVersion @@ -1335,7 +1331,6 @@ module adminweb 'modules/app/adminweb.bicep' = { { AZURE_BLOB_ACCOUNT_NAME: storageAccountName AZURE_BLOB_CONTAINER_NAME: blobContainerName - // Endpoints constructed from resource names to avoid implicit dependencies on AI service modules AZURE_FORM_RECOGNIZER_ENDPOINT: 'https://${formRecognizerName}.cognitiveservices.azure.com/' AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? 'https://${computerVisionName}.cognitiveservices.azure.com/' : '' AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION: computerVisionVectorizeImageApiVersion @@ -1443,7 +1438,6 @@ module function 'modules/app/function.bicep' = { { AZURE_BLOB_ACCOUNT_NAME: storageAccountName AZURE_BLOB_CONTAINER_NAME: blobContainerName - // Endpoints constructed from resource names to avoid implicit dependencies on AI service modules AZURE_FORM_RECOGNIZER_ENDPOINT: 'https://${formRecognizerName}.cognitiveservices.azure.com/' AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? 'https://${computerVisionName}.cognitiveservices.azure.com/' : '' AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION: computerVisionVectorizeImageApiVersion @@ -1575,7 +1569,6 @@ module formrecognizer 'modules/core/ai/cognitiveservices.bicep' = { : [] ) } - // Implicit dependency on the specific DNS zone is established via the privateDnsZoneResourceId param reference } module contentsafety 'modules/core/ai/cognitiveservices.bicep' = { @@ -1615,7 +1608,6 @@ module contentsafety 'modules/core/ai/cognitiveservices.bicep' = { : [] ) } - // Implicit dependency on the specific DNS zone is established via the privateDnsZoneResourceId param reference } // If advanced image processing is used, storage account already should be publicly accessible. diff --git a/infra/main.json b/infra/main.json index b0881f150..0ac0292ed 100644 --- a/infra/main.json +++ b/infra/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.41.2.15936", - "templateHash": "13064725685019502849" + "templateHash": "4688738135405051461" } }, "parameters": { @@ -54510,9 +54510,9 @@ } }, "dependsOn": [ - "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageQueue)]", - "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageFile)]", "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageFile)]", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageQueue)]", "managedIdentityModule", "virtualNetwork" ] diff --git a/scripts/post_deployment_setup.ps1 b/scripts/post_deployment_setup.ps1 index 015e5b770..3c064636c 100644 --- a/scripts/post_deployment_setup.ps1 +++ b/scripts/post_deployment_setup.ps1 @@ -43,22 +43,20 @@ $currentIdentityOid = $null $currentIdentityDisplay = $null $principalType = "User" -# Try signed-in user first (single API call to get both id and userPrincipalName) -$userInfo = az ad signed-in-user show 2>$null | ConvertFrom-Json -if ($userInfo) { +# Try signed-in user first +$currentIdentityOid = az ad signed-in-user show --query "id" -o tsv 2>$null +if ($currentIdentityOid) { $identityType = "user" - $currentIdentityOid = $userInfo.id - $currentIdentityDisplay = $userInfo.userPrincipalName + $currentIdentityDisplay = az ad signed-in-user show --query "userPrincipalName" -o tsv 2>$null $principalType = "User" Write-Host "✓ Detected identity type: User ($currentIdentityDisplay)" } else { - # Fallback to service principal (single API call per resource) + # Fallback to service principal $spAppId = az account show --query "user.name" -o tsv 2>$null if ($spAppId -and $spAppId -ne "null") { - $spInfo = az ad sp show --id $spAppId 2>$null | ConvertFrom-Json - if ($spInfo) { - $currentIdentityOid = $spInfo.id - $currentIdentityDisplay = $spInfo.displayName + $currentIdentityOid = az ad sp show --id $spAppId --query "id" -o tsv 2>$null + $currentIdentityDisplay = az ad sp show --id $spAppId --query "displayName" -o tsv 2>$null + if ($currentIdentityOid) { $identityType = "servicePrincipal" $principalType = "ServicePrincipal" Write-Host "✓ Detected identity type: Service Principal ($currentIdentityDisplay, OID: $currentIdentityOid)" @@ -127,21 +125,21 @@ Write-Host "" Write-Host "--- Step 1: Set Function App Client Key ---" # Discover function app -$functionAppName = az functionapp list --resource-group $ResourceGroupName --query "[0].name" -o tsv 2>$null -if (-not $functionAppName) { +$functionApps = az functionapp list --resource-group $ResourceGroupName --query "[].name" -o tsv 2>$null +if (-not $functionApps) { Write-Warning "⚠ No function apps found in resource group '$ResourceGroupName'. Skipping function key setup." } else { - $functionAppName = $functionAppName.Trim() + $functionAppName = ($functionApps -split "`n")[0].Trim() Write-Host "✓ Discovered function app: $functionAppName" # Discover key vault - $keyVaultName = az keyvault list --resource-group $ResourceGroupName --query "[0].name" -o tsv 2>$null - if (-not $keyVaultName) { + $keyVaults = az keyvault list --resource-group $ResourceGroupName --query "[].name" -o tsv 2>$null + if (-not $keyVaults) { Write-Warning "⚠ No Key Vault found. Skipping function key setup." } else { - $keyVaultName = $keyVaultName.Trim() + $keyVaultName = ($keyVaults -split "`n")[0].Trim() Write-Host "✓ Discovered Key Vault: $keyVaultName" # Ensure the current identity has 'Key Vault Secrets User' role on the Key Vault @@ -228,12 +226,12 @@ else { Write-Host "" Write-Host "--- Step 2: Create PostgreSQL Tables ---" -$serverFqdn = az postgres flexible-server list --resource-group $ResourceGroupName --query "[0].fullyQualifiedDomainName" -o tsv 2>$null -if (-not $serverFqdn) { +$pgServers = az postgres flexible-server list --resource-group $ResourceGroupName --query "[].fullyQualifiedDomainName" -o tsv 2>$null +if (-not $pgServers) { Write-Host "No PostgreSQL Flexible Server found in resource group. Skipping table creation." } else { - $serverFqdn = $serverFqdn.Trim() + $serverFqdn = ($pgServers -split "`n")[0].Trim() $serverName = $serverFqdn.Split('.')[0] Write-Host "✓ Discovered PostgreSQL server: $serverName ($serverFqdn)" diff --git a/scripts/post_deployment_setup.sh b/scripts/post_deployment_setup.sh index 7b144c248..fcd8c23a4 100644 --- a/scripts/post_deployment_setup.sh +++ b/scripts/post_deployment_setup.sh @@ -51,27 +51,23 @@ CURRENT_IDENTITY_OID="" CURRENT_IDENTITY_DISPLAY="" PRINCIPAL_TYPE="User" -# Try signed-in user first (single API call to get full JSON, then parse both fields) -USER_JSON=$(az ad signed-in-user show 2>/dev/null || true) -if [ -n "$USER_JSON" ]; then +# Try signed-in user first +CURRENT_IDENTITY_OID=$(az ad signed-in-user show --query "id" -o tsv 2>/dev/null || true) +if [ -n "$CURRENT_IDENTITY_OID" ]; then IDENTITY_TYPE="user" - CURRENT_IDENTITY_OID=$(echo "$USER_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])" 2>/dev/null || true) - CURRENT_IDENTITY_DISPLAY=$(echo "$USER_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['userPrincipalName'])" 2>/dev/null || true) + CURRENT_IDENTITY_DISPLAY=$(az ad signed-in-user show --query "userPrincipalName" -o tsv 2>/dev/null || true) PRINCIPAL_TYPE="User" echo "✓ Detected identity type: User (${CURRENT_IDENTITY_DISPLAY})" else - # Fallback to service principal (single API call per resource) + # Fallback to service principal — get the SP's app ID from the current account SP_APP_ID=$(az account show --query "user.name" -o tsv 2>/dev/null || true) if [ -n "$SP_APP_ID" ] && [ "$SP_APP_ID" != "null" ]; then - SP_JSON=$(az ad sp show --id "$SP_APP_ID" 2>/dev/null || true) - if [ -n "$SP_JSON" ]; then - CURRENT_IDENTITY_OID=$(echo "$SP_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])" 2>/dev/null || true) - CURRENT_IDENTITY_DISPLAY=$(echo "$SP_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['displayName'])" 2>/dev/null || true) - if [ -n "$CURRENT_IDENTITY_OID" ]; then - IDENTITY_TYPE="servicePrincipal" - PRINCIPAL_TYPE="ServicePrincipal" - echo "✓ Detected identity type: Service Principal (${CURRENT_IDENTITY_DISPLAY}, OID: ${CURRENT_IDENTITY_OID})" - fi + CURRENT_IDENTITY_OID=$(az ad sp show --id "$SP_APP_ID" --query "id" -o tsv 2>/dev/null || true) + CURRENT_IDENTITY_DISPLAY=$(az ad sp show --id "$SP_APP_ID" --query "displayName" -o tsv 2>/dev/null || true) + if [ -n "$CURRENT_IDENTITY_OID" ]; then + IDENTITY_TYPE="servicePrincipal" + PRINCIPAL_TYPE="ServicePrincipal" + echo "✓ Detected identity type: Service Principal (${CURRENT_IDENTITY_DISPLAY}, OID: ${CURRENT_IDENTITY_OID})" fi fi fi