diff --git a/documents/CustomizeData.md b/documents/CustomizeData.md index 49d662562..95cc9bf1d 100644 --- a/documents/CustomizeData.md +++ b/documents/CustomizeData.md @@ -21,3 +21,17 @@ If you would like to update the solution to leverage your own data please follow ``` a. resourcegroupname_param - the name of the resource group. +> Note (WAF‑aligned deployments): If you deployed the solution with the WAF / private networking option enabled, you must run the data processing script **from inside the deployed VM (jumpbox / processing VM)** so it can reach the private endpoints. Follow these steps: +> +> 1. Connect to the VM (Azure Bastion, SSH, or RDP depending on OS). +> 2. Ensure the repo (or the `infra/scripts` folder) is present. If not, clone or pull it. +> 3. Open a Bash-compatible shell (Git Bash on Windows, or native bash on Linux). +> 4. Run `az login` (add `--tenant ` if required by your org policy). +> 5. Navigate to `infra/scripts` and execute: +> ```bash +> bash run_process_data_scripts.sh +> ``` +> 6. Replace `` with the name of the resource group you deployed (same value used for `resourcegroupname_param`). +> +> Tip: If Azure CLI is not installed on the VM, install it first (see official docs) before running the script. + diff --git a/documents/CustomizingAzdParameters.md b/documents/CustomizingAzdParameters.md index bccb3eb9e..40e286049 100644 --- a/documents/CustomizingAzdParameters.md +++ b/documents/CustomizingAzdParameters.md @@ -24,7 +24,8 @@ By default this template will use the environment name as the prefix to prevent | `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID` | string | Guide to get your [Existing Workspace ID](/documents/re-use-log-analytics.md) | Reuses an existing Log Analytics Workspace instead of creating a new one. | | `USE_LOCAL_BUILD` | string | `false` | Indicates whether to use a local container build for deployment. | | `AZURE_EXISTING_AI_PROJECT_RESOURCE_ID` | string | `` | Reuses an existing AIFoundry and AIFoundryProject instead of creating a new one. | - +| `AZURE_ENV_VM_ADMIN_USERNAME` | string | `take(newGuid(), 20)` | The administrator username for the virtual machine. | +| `AZURE_ENV_VM_ADMIN_PASSWORD` | string | `newGuid()` | The administrator password for the virtual machine. | ## How to Set a Parameter diff --git a/infra/create-sql-user-and-role.bicep b/infra/create-sql-user-and-role.bicep deleted file mode 100644 index 8b35259d7..000000000 --- a/infra/create-sql-user-and-role.bicep +++ /dev/null @@ -1,62 +0,0 @@ -targetScope = 'resourceGroup' - -@description('Required. The Azure region for the resource.') -param location string - -@description('Required. The tags to associate with this resource.') -param tags object = {} - -@description('Required. The database roles to assign to the user.') -param databaseRoles string[] = ['db_datareader'] - -@description('Required. The name of the User Assigned Managed Identity to be used.') -param managedIdentityName string - -@description('Required. The principal (or object) ID of the user to create.') -param principalId string - -@description('Required. The name of the user to create.') -param principalName string - -@description('Required. The name of the SQL Database resource.') -param sqlDatabaseName string - -@description('Required. The name of the SQL Server resource.') -param sqlServerName string - -@description('Do not set - unique script ID to force the script to run.') -param uniqueScriptId string = newGuid() - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = { - name: managedIdentityName -} - -resource createSqlUserAndRole 'Microsoft.Resources/deploymentScripts@2023-08-01' = { - name: 'sqlUserRole-${guid(principalId, sqlServerName, sqlDatabaseName)}' - location: location - tags: tags - kind: 'AzurePowerShell' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - forceUpdateTag: uniqueScriptId - azPowerShellVersion: '11.0' - retentionInterval: 'PT1H' - cleanupPreference: 'OnSuccess' - arguments: join( - [ - '-SqlServerName \'${sqlServerName}\'' - '-SqlDatabaseName \'${sqlDatabaseName}\'' - '-ClientId \'${principalId}\'' - '-DisplayName \'${principalName}\'' - '-DatabaseRoles \'${join(databaseRoles, ',')}\'' - ], - ' ' - ) - scriptContent: loadTextContent('./scripts/add_user_scripts/create-sql-user-and-role.ps1') - } -} diff --git a/infra/deploy_ai_foundry.bicep b/infra/deploy_ai_foundry.bicep deleted file mode 100644 index 0901e467e..000000000 --- a/infra/deploy_ai_foundry.bicep +++ /dev/null @@ -1,606 +0,0 @@ -// Creates Azure dependent resources for Azure AI studio - -@minLength(3) -@maxLength(16) -@description('Required. Contains Solution Name') -param solutionName string - -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@description('Optional. Contains KeyVault Name') -param keyVaultName string='' - -@description('Required. Contains CU Location') -param cuLocation string - -@description('Required. Contains type of Deployment') -param deploymentType string - -@description('Required. Contains GPT mode Name') -param gptModelName string - -@description('Required. Contains GPT Model Version') -param gptModelVersion string - -@description('Required. Contains Open AI API version') -param azureOpenAIApiVersion string - -@description('Required. Contains GPT Deployment Capacity') -param gptDeploymentCapacity int - -@description('Required. Contains Embedding Model') -param embeddingModel string - -@description('Required. Contains Embedding Deployment Capacity') -param embeddingDeploymentCapacity int - -@description('Optional. Contains Managed Identity ObjectID') -param managedIdentityObjectId string='' - -@description('Optional. Contains existing Log Analytics Workspace ID') -param existingLogAnalyticsWorkspaceId string = '' - -@description('Optional. Contains existing AI Project Resource ID') -param azureExistingAIProjectResourceId string = '' - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -//var abbrs = loadJsonContent('./abbreviations.json') -var aiServicesName = 'aisa-${solutionName}' -var aiServicesName_cu = 'aisa-${solutionName}-cu' -var location_cu = cuLocation -var workspaceName = 'log-${solutionName}' -var applicationInsightsName = 'appi-${solutionName}' -var keyvaultName = 'kv-${solutionName}' -var location = solutionLocation //'eastus2' -var aiProjectName = 'proj-${solutionName}' -var aiSearchName = 'srch-${solutionName}' -var aiSearchConnectionName = 'myCon-${solutionName}' - -var aiModelDeployments = [ - { - name: gptModelName - model: gptModelName - sku: { - name: deploymentType - capacity: gptDeploymentCapacity - } - version: gptModelVersion - raiPolicyName: 'Microsoft.Default' - } - { - name: embeddingModel - model: embeddingModel - sku: { - name: 'GlobalStandard' - capacity: embeddingDeploymentCapacity - } - raiPolicyName: 'Microsoft.Default' - } -] - -var useExisting = !empty(existingLogAnalyticsWorkspaceId) -var existingLawSubscription = useExisting ? split(existingLogAnalyticsWorkspaceId, '/')[2] : '' -var existingLawResourceGroup = useExisting ? split(existingLogAnalyticsWorkspaceId, '/')[4] : '' -var existingLawName = useExisting ? split(existingLogAnalyticsWorkspaceId, '/')[8] : '' - -var existingOpenAIEndpoint = !empty(azureExistingAIProjectResourceId) ? format('https://{0}.openai.azure.com/', split(azureExistingAIProjectResourceId, '/')[8]) : '' -var existingProjEndpoint = !empty(azureExistingAIProjectResourceId) ? format('https://{0}.services.ai.azure.com/api/projects/{1}', split(azureExistingAIProjectResourceId, '/')[8], split(azureExistingAIProjectResourceId, '/')[10]) : '' -var existingAIServicesName = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[8] : '' -var existingAIProjectName = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[10] : '' -var existingAIServiceSubscription = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[2] : subscription().subscriptionId -var existingAIServiceResourceGroup = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[4] : resourceGroup().name - -resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { - name: keyVaultName -} - -resource existingLogAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = if (useExisting) { - name: existingLawName - scope: resourceGroup(existingLawSubscription ,existingLawResourceGroup) -} - -resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2023-09-01' = if (!useExisting){ - name: workspaceName - location: location - tags: tags - properties: { - retentionInDays: 30 - sku: { - name: 'PerGB2018' - } - } -} - -resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { - name: applicationInsightsName - location: location - kind: 'web' - properties: { - Application_Type: 'web' - publicNetworkAccessForIngestion: 'Enabled' - publicNetworkAccessForQuery: 'Disabled' - WorkspaceResourceId: useExisting ? existingLogAnalyticsWorkspace.id : logAnalytics.id - } - tags : tags -} - -resource aiServices 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' = if (empty(azureExistingAIProjectResourceId)) { - name: aiServicesName - location: location - sku: { - name: 'S0' - } - kind: 'AIServices' - identity: { - type: 'SystemAssigned' - } - properties: { - allowProjectManagement: true - customSubDomainName: aiServicesName - networkAcls: { - defaultAction: 'Allow' - virtualNetworkRules: [] - ipRules: [] - } - publicNetworkAccess: 'Enabled' - disableLocalAuth: false //needs to be false to access keys - } - tags : tags -} - -module existing_aiServicesModule 'existing_foundry_project.bicep' = if (!empty(azureExistingAIProjectResourceId)) { - name: 'existing_foundry_project' - scope: resourceGroup(existingAIServiceSubscription, existingAIServiceResourceGroup) - params: { - aiServicesName: existingAIServicesName - aiProjectName: existingAIProjectName - } -} - -resource aiServices_CU 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' = { - name: aiServicesName_cu - location: location_cu - sku: { - name: 'S0' - } - kind: 'AIServices' - identity: { - type: 'SystemAssigned' - } - properties: { - allowProjectManagement: true - customSubDomainName: aiServicesName_cu - networkAcls: { - defaultAction: 'Allow' - virtualNetworkRules: [] - ipRules: [] - } - publicNetworkAccess: 'Enabled' - disableLocalAuth: false //needs to be false to access keys - } - tags : tags -} - -@batchSize(1) -resource aiServicesDeployments 'Microsoft.CognitiveServices/accounts/deployments@2025-04-01-preview' = [for aiModeldeployment in aiModelDeployments: if (empty(azureExistingAIProjectResourceId)) { - parent: aiServices //aiServices_m - name: aiModeldeployment.name - properties: { - model: { - format: 'OpenAI' - name: aiModeldeployment.model - } - raiPolicyName: aiModeldeployment.raiPolicyName - } - sku:{ - name: aiModeldeployment.sku.name - capacity: aiModeldeployment.sku.capacity - } - tags : tags -}] - -resource aiSearch 'Microsoft.Search/searchServices@2024-06-01-preview' = { - name: aiSearchName - location: solutionLocation - sku: { - name: 'basic' - } - identity: { - type: 'SystemAssigned' - } - properties: { - replicaCount: 1 - partitionCount: 1 - hostingMode: 'default' - publicNetworkAccess: 'enabled' - networkRuleSet: { - ipRules: [] - } - encryptionWithCmk: { - enforcement: 'Unspecified' - } - disableLocalAuth: true - semanticSearch: 'free' - } - tags : tags -} - -resource aiProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' = if (empty(azureExistingAIProjectResourceId)) { - parent: aiServices - name: aiProjectName - location: solutionLocation - kind: 'AIServices' - identity: { - type: 'SystemAssigned' - } - properties: {} - tags : tags -} - -resource aiproject_aisearch_connection_new 'Microsoft.CognitiveServices/accounts/projects/connections@2025-04-01-preview' = if (empty(azureExistingAIProjectResourceId)) { - name: aiSearchConnectionName - parent: aiProject - properties: { - category: 'CognitiveSearch' - target: 'https://${aiSearchName}.search.windows.net' - authType: 'AAD' - isSharedToAll: true - metadata: { - ApiType: 'Azure' - ResourceId: aiSearch.id - location: aiSearch.location - } - } -} - -module existing_AIProject_SearchConnectionModule 'deploy_aifp_aisearch_connection.bicep' = if (!empty(azureExistingAIProjectResourceId)) { - name: 'aiProjectSearchConnectionDeployment' - scope: resourceGroup(existingAIServiceSubscription, existingAIServiceResourceGroup) - params: { - existingAIProjectName: existingAIProjectName - existingAIServicesName: existingAIServicesName - aiSearchName: aiSearchName - aiSearchResourceId: aiSearch.id - aiSearchLocation: aiSearch.location - aiSearchConnectionName: aiSearchConnectionName - } -} - -resource aiUser 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: '53ca6127-db72-4b80-b1b0-d745d6d5456d' -} - - -resource assignFoundryRoleToMI 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (empty(azureExistingAIProjectResourceId)) { - name: guid(resourceGroup().id, aiServices.id, aiUser.id) - scope: aiServices - properties: { - principalId: managedIdentityObjectId - roleDefinitionId: aiUser.id - principalType: 'ServicePrincipal' - } -} -module assignFoundryRoleToMIExisting 'deploy_foundry_role_assignment.bicep' = if (!empty(azureExistingAIProjectResourceId)) { - name: 'assignFoundryRoleToMI' - scope: resourceGroup(existingAIServiceSubscription, existingAIServiceResourceGroup) - params: { - roleDefinitionId: aiUser.id - roleAssignmentName: guid(resourceGroup().id, managedIdentityObjectId, aiUser.id, 'foundry') - aiServicesName: existingAIServicesName - aiProjectName: existingAIProjectName - principalId: managedIdentityObjectId - aiLocation: existing_aiServicesModule.outputs.location - aiKind: existing_aiServicesModule.outputs.kind - aiSkuName: existing_aiServicesModule.outputs.skuName - customSubDomainName: existing_aiServicesModule.outputs.customSubDomainName - publicNetworkAccess: existing_aiServicesModule.outputs.publicNetworkAccess - enableSystemAssignedIdentity: true - defaultNetworkAction: existing_aiServicesModule.outputs.defaultNetworkAction - vnetRules: existing_aiServicesModule.outputs.vnetRules - ipRules: existing_aiServicesModule.outputs.ipRules - aiModelDeployments: aiModelDeployments // Pass the model deployments to the module if model not already deployed - } -} - -resource assignAiUserToAiFoundryCU 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, aiServices_CU.id, aiUser.id) - scope: aiServices_CU - properties: { - principalId: managedIdentityObjectId - roleDefinitionId: aiUser.id - principalType: 'ServicePrincipal' - } -} - -resource cognitiveServicesOpenAIUser 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' -} - -resource assignOpenAIRoleToAISearch 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (empty(azureExistingAIProjectResourceId)) { - name: guid(resourceGroup().id, aiServices.id, cognitiveServicesOpenAIUser.id) - scope: aiServices - properties: { - principalId: aiSearch.identity.principalId - roleDefinitionId: cognitiveServicesOpenAIUser.id - principalType: 'ServicePrincipal' - } -} - -module assignOpenAIRoleToAISearchExisting 'deploy_foundry_role_assignment.bicep' = if (!empty(azureExistingAIProjectResourceId)) { - name: 'assignOpenAIRoleToAISearchExisting' - scope: resourceGroup(existingAIServiceSubscription, existingAIServiceResourceGroup) - params: { - roleDefinitionId: cognitiveServicesOpenAIUser.id - roleAssignmentName: guid(resourceGroup().id, aiSearch.id, cognitiveServicesOpenAIUser.id, 'openai-foundry') - aiServicesName: existingAIServicesName - aiProjectName: existingAIProjectName - principalId: aiSearch.identity.principalId - enableSystemAssignedIdentity: false - } -} - -resource searchIndexDataReader 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: '1407120a-92aa-4202-b7e9-c0e197c71c8f' -} - -resource assignSearchIndexDataReaderToAiProject 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (empty(azureExistingAIProjectResourceId)) { - name: guid(resourceGroup().id, aiProject.id, searchIndexDataReader.id) - scope: aiSearch - properties: { - principalId: aiProject.identity.principalId - roleDefinitionId: searchIndexDataReader.id - principalType: 'ServicePrincipal' - } -} - -resource assignSearchIndexDataReaderToExistingAiProject 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (!empty(azureExistingAIProjectResourceId)) { - name: guid(resourceGroup().id, existingAIProjectName, searchIndexDataReader.id, 'Existing') - scope: aiSearch - properties: { - principalId: assignOpenAIRoleToAISearchExisting.outputs.aiProjectPrincipalId - roleDefinitionId: searchIndexDataReader.id - principalType: 'ServicePrincipal' - } -} - -resource searchServiceContributor 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: '7ca78c08-252a-4471-8644-bb5ff32d4ba0' -} - -resource assignSearchServiceContributorToAiProject 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (empty(azureExistingAIProjectResourceId)) { - name: guid(resourceGroup().id, aiProject.id, searchServiceContributor.id) - scope: aiSearch - properties: { - principalId: aiProject.identity.principalId - roleDefinitionId: searchServiceContributor.id - principalType: 'ServicePrincipal' - } -} - -resource assignSearchServiceContributorToExistingAiProject 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (!empty(azureExistingAIProjectResourceId)) { - name: guid(resourceGroup().id, existingAIProjectName, searchServiceContributor.id, 'Existing') - scope: aiSearch - properties: { - principalId: assignOpenAIRoleToAISearchExisting.outputs.aiProjectPrincipalId - roleDefinitionId: searchServiceContributor.id - principalType: 'ServicePrincipal' - } -} - -resource searchIndexDataContributor 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' -} - -resource assignSearchIndexDataContributorToMI 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, aiProject.id, searchIndexDataContributor.id) - scope: aiSearch - properties: { - principalId: managedIdentityObjectId - roleDefinitionId: searchIndexDataContributor.id - principalType: 'ServicePrincipal' - } -} - -resource tenantIdEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'TENANT-ID' - properties: { - value: subscription().tenantId - } - tags : tags -} - -resource azureOpenAIInferenceEndpoint 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-INFERENCE-ENDPOINT' - properties: { - value:'' - } - tags : tags -} - -resource azureOpenAIInferenceKey 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-INFERENCE-KEY' - properties: { - value:'' - } - tags : tags -} - -resource azureOpenAIDeploymentModel 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-DEPLOYMENT-MODEL' - properties: { - value: gptModelName - } - tags : tags -} - -resource azureOpenAIApiVersionEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-PREVIEW-API-VERSION' - properties: { - value: azureOpenAIApiVersion //'2024-02-15-preview' - } - tags : tags -} - -resource azureOpenAIEndpointEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-ENDPOINT' - properties: { - value: !empty(existingOpenAIEndpoint) ? existingOpenAIEndpoint : aiServices.properties.endpoints['OpenAI Language Model Instance API'] //aiServices_m.properties.endpoint - } - tags : tags -} - -resource azureOpenAIEmbeddingDeploymentModel 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-EMBEDDING-MODEL' - properties: { - value: embeddingModel - } - tags : tags -} - -resource azureOpenAICUEndpointEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-CU-ENDPOINT' - properties: { - value: aiServices_CU.properties.endpoints['OpenAI Language Model Instance API'] - } - tags : tags -} - -resource azureOpenAICUApiVersionEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-CU-VERSION' - properties: { - value: '?api-version=2024-12-01-preview' - } - tags : tags -} - -resource azureSearchServiceEndpointEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-SEARCH-ENDPOINT' - properties: { - value: 'https://${aiSearch.name}.search.windows.net' - } - tags : tags -} - -resource azureSearchServiceEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-SEARCH-SERVICE' - properties: { - value: aiSearch.name - } - tags : tags -} - -resource azureSearchIndexEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-SEARCH-INDEX' - properties: { - value: 'transcripts_index' - } - tags : tags -} - -resource cogServiceEndpointEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'COG-SERVICES-ENDPOINT' - properties: { - value: !empty(existingOpenAIEndpoint) ? existingOpenAIEndpoint : aiServices.properties.endpoints['OpenAI Language Model Instance API'] - } - tags : tags -} - -resource cogServiceNameEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'COG-SERVICES-NAME' - properties: { - value: aiServicesName - } - tags : tags -} - -resource azureSubscriptionIdEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-SUBSCRIPTION-ID' - properties: { - value: subscription().subscriptionId - } - tags : tags -} - -resource resourceGroupNameEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-RESOURCE-GROUP' - properties: { - value: resourceGroup().name - } - tags : tags -} - -resource azureLocatioEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-LOCATION' - properties: { - value: solutionLocation - } - tags : tags -} - -@description('Contains KeyVault Name') -output keyvaultName string = keyvaultName - -@description('Contains KeyVault ID') -output keyvaultId string = keyVault.id - -@description('Contains AI Services Target') -output aiServicesTarget string = !empty(existingOpenAIEndpoint) ? existingOpenAIEndpoint : aiServices.properties.endpoints['OpenAI Language Model Instance API'] //aiServices_m.properties.endpoint - -@description('Contains AI Services Name') -output aiServicesName string = !empty(existingAIServicesName) ? existingAIServicesName : aiServicesName - -@description('Contains Search Name') -output aiSearchName string = aiSearchName - -@description('Contains Search ID') -output aiSearchId string = aiSearch.id - -@description('Contains AI Search Target') -output aiSearchTarget string = 'https://${aiSearch.name}.search.windows.net' - -@description('Contains AI Search Service Name') -output aiSearchService string = aiSearch.name - -@description('Contains AI Project Name') -output aiProjectName string = !empty(existingAIProjectName) ? existingAIProjectName : aiProject.name - -@description('Contains AI Search Connection Name') -output aiSearchConnectionName string = aiSearchConnectionName - -@description('Contains Application Insights ID') -output applicationInsightsId string = applicationInsights.id - -@description('Contains LogAnalytics Workspace Resource Name') -output logAnalyticsWorkspaceResourceName string = useExisting ? existingLogAnalyticsWorkspace.name : logAnalytics.name - -@description('Contains LogAnalytics Workspace Resource Group') -output logAnalyticsWorkspaceResourceGroup string = useExisting ? existingLawResourceGroup : resourceGroup().name - -@description('Contains LogAnalytics Workspace Subscription') -output logAnalyticsWorkspaceSubscription string = useExisting ? existingLawSubscription : subscription().subscriptionId - -@description('Contains Project Endpoint') -output projectEndpoint string = !empty(existingProjEndpoint) ? existingProjEndpoint : aiProject.properties.endpoints['AI Foundry API'] - -@description('Contains Application Insights Connection String') -output applicationInsightsConnectionString string = applicationInsights.properties.ConnectionString diff --git a/infra/deploy_aifp_aisearch_connection.bicep b/infra/deploy_aifp_aisearch_connection.bicep deleted file mode 100644 index 5a229e3dd..000000000 --- a/infra/deploy_aifp_aisearch_connection.bicep +++ /dev/null @@ -1,32 +0,0 @@ -@description('Required. Contains existing AI Project Name') -param existingAIProjectName string - -@description('Required. Contains existing AI Services Name') -param existingAIServicesName string - -@description('Required. Contains AI Search Name') -param aiSearchName string - -@description('Required. Contains AI Search Resource ID') -param aiSearchResourceId string - -@description('Required. Contains AI Search Location') -param aiSearchLocation string - -@description('Required. Contains AI Search Connection Name') -param aiSearchConnectionName string - -resource projectAISearchConnection 'Microsoft.CognitiveServices/accounts/projects/connections@2025-04-01-preview' = { - name: '${existingAIServicesName}/${existingAIProjectName}/${aiSearchConnectionName}' - properties: { - category: 'CognitiveSearch' - target: 'https://${aiSearchName}.search.windows.net' - authType: 'AAD' - isSharedToAll: true - metadata: { - ApiType: 'Azure' - ResourceId: aiSearchResourceId - location: aiSearchLocation - } - } -} diff --git a/infra/deploy_app_service.bicep b/infra/deploy_app_service.bicep deleted file mode 100644 index 4a9e6fac6..000000000 --- a/infra/deploy_app_service.bicep +++ /dev/null @@ -1,86 +0,0 @@ -// ========== Key Vault ========== // -targetScope = 'resourceGroup' - -@description('Required. Contains Solution Name.') -param solutionName string - -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@secure() -@description('Required. Contains App Settings.') -param appSettings object = {} - -@description('Required. Contains App Service Plan ID.') -param appServicePlanId string - -@description('Required. Contains App Image Name.') -param appImageName string - -@description('Optional. Contains User Assigned Identity ID.') -param userassignedIdentityId string = '' - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -resource appService 'Microsoft.Web/sites@2020-06-01' = { - name: solutionName - location: solutionLocation - tags : tags - identity: userassignedIdentityId == '' ? { - type: 'SystemAssigned' - } : { - type: 'SystemAssigned, UserAssigned' - userAssignedIdentities: { - '${userassignedIdentityId}': {} - } - } - properties: { - serverFarmId: appServicePlanId - siteConfig: { - alwaysOn: true - ftpsState: 'Disabled' - linuxFxVersion: appImageName - } - } - resource basicPublishingCredentialsPoliciesFtp 'basicPublishingCredentialsPolicies' = { - name: 'ftp' - properties: { - allow: false - } - } - resource basicPublishingCredentialsPoliciesScm 'basicPublishingCredentialsPolicies' = { - name: 'scm' - properties: { - allow: false - } - } -} - -module configAppSettings 'deploy_appservice-appsettings.bicep' = { - name: '${appService.name}-appSettings' - params: { - name: appService.name - appSettings: appSettings - } -} - -resource configLogs 'Microsoft.Web/sites/config@2022-03-01' = { - name: 'logs' - parent: appService - properties: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } - } - dependsOn: [configAppSettings] -} - - -@description('Contains Identity Principle ID.') -output identityPrincipalId string = appService.identity.principalId - -@description('Contains App URL.') -output appUrl string = 'https://${solutionName}.azurewebsites.net' - diff --git a/infra/deploy_app_service_plan.bicep b/infra/deploy_app_service_plan.bicep deleted file mode 100644 index 47a4fc4d8..000000000 --- a/infra/deploy_app_service_plan.bicep +++ /dev/null @@ -1,35 +0,0 @@ -metadata description = 'Creates an Azure App Service plan.' - -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@description('Required. Name of App Service plan.') -param HostingPlanName string - -@description('Required. The pricing tier for the App Service plan.') -@allowed( - ['F1', 'D1', 'B1', 'B2', 'B3', 'S1', 'S2', 'S3', 'P1', 'P2', 'P3', 'P4','P0v3'] -) -param HostingPlanSku string = 'B2' - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -resource HostingPlan 'Microsoft.Web/serverfarms@2020-06-01' = { - name: HostingPlanName - location: solutionLocation - sku: { - name: HostingPlanSku - } - properties: { - reserved: true - } - kind: 'linux' - tags : tags -} - -@description('Contains Hosting Plan ID.') -output id string = HostingPlan.id - -@description('Contains Hosting Plan Name.') -output name string = HostingPlan.name diff --git a/infra/deploy_appservice-appsettings.bicep b/infra/deploy_appservice-appsettings.bicep deleted file mode 100644 index bd9ffe825..000000000 --- a/infra/deploy_appservice-appsettings.bicep +++ /dev/null @@ -1,17 +0,0 @@ -metadata description = 'Updates app settings for an Azure App Service.' -@description('Required. The name of the app service resource within the current resource group scope') -param name string - -@description('Required. The app settings to be applied to the app service') -@secure() -param appSettings object - -resource appService 'Microsoft.Web/sites@2022-03-01' existing = { - name: name -} - -resource settings 'Microsoft.Web/sites/config@2022-03-01' = { - name: 'appsettings' - parent: appService - properties: appSettings -} diff --git a/infra/deploy_backend_docker.bicep b/infra/deploy_backend_docker.bicep deleted file mode 100644 index 2d6ac8eb7..000000000 --- a/infra/deploy_backend_docker.bicep +++ /dev/null @@ -1,221 +0,0 @@ -@description('Required. Contains the Image Tag.') -param imageTag string - -@description('Required. Contains ACR Name.') -param acrName string - -@description('Required. Contains Application Insights ID.') -param applicationInsightsId string - -@description('Required. Contains Solution Location.') -param solutionLocation string - -@secure() -@description('Required. Contains App Settings.') -param appSettings object = {} - -@description('Required. Contains App Service Plan ID.') -param appServicePlanId string - -@description('Required. Contains User Assigned Identity ID.') -param userassignedIdentityId string - -@description('Required. Contains KeyVault Name.') -param keyVaultName string - -@description('Required. Contains AI Services Name.') -param aiServicesName string - -@description('Required. Contains Existing AI Project Resource ID.') -param azureExistingAIProjectResourceId string = '' - -@description('Required. Contains AI Search Name') -param aiSearchName string - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -var existingAIServiceSubscription = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[2] : subscription().subscriptionId -var existingAIServiceResourceGroup = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[4] : resourceGroup().name -var existingAIServicesName = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[8] : '' -var existingAIProjectName = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[10] : '' - -var imageName = 'DOCKER|${acrName}.azurecr.io/km-api:${imageTag}' -param name string -var reactAppLayoutConfig ='''{ - "appConfig": { - "THREE_COLUMN": { - "DASHBOARD": 50, - "CHAT": 33, - "CHATHISTORY": 17 - }, - "TWO_COLUMN": { - "DASHBOARD_CHAT": { - "DASHBOARD": 65, - "CHAT": 35 - }, - "CHAT_CHATHISTORY": { - "CHAT": 80, - "CHATHISTORY": 20 - } - } - }, - "charts": [ - { - "id": "SATISFIED", - "name": "Satisfied", - "type": "card", - "layout": { "row": 1, "column": 1, "height": 11 } - }, - { - "id": "TOTAL_CALLS", - "name": "Total Calls", - "type": "card", - "layout": { "row": 1, "column": 2, "span": 1 } - }, - { - "id": "AVG_HANDLING_TIME", - "name": "Average Handling Time", - "type": "card", - "layout": { "row": 1, "column": 3, "span": 1 } - }, - { - "id": "SENTIMENT", - "name": "Topics Overview", - "type": "donutchart", - "layout": { "row": 2, "column": 1, "width": 40, "height": 44.5 } - }, - { - "id": "AVG_HANDLING_TIME_BY_TOPIC", - "name": "Average Handling Time By Topic", - "type": "bar", - "layout": { "row": 2, "column": 2, "row-span": 2, "width": 60 } - }, - { - "id": "TOPICS", - "name": "Trending Topics", - "type": "table", - "layout": { "row": 3, "column": 1, "span": 2 } - }, - { - "id": "KEY_PHRASES", - "name": "Key Phrases", - "type": "wordcloud", - "layout": { "row": 3, "column": 2, "height": 44.5 } - } - ] -}''' - -module appService 'deploy_app_service.bicep' = { - name: '${name}-app-module' - params: { - solutionName: name - solutionLocation:solutionLocation - appServicePlanId: appServicePlanId - appImageName: imageName - userassignedIdentityId:userassignedIdentityId - appSettings: union( - appSettings, - { - APPINSIGHTS_INSTRUMENTATIONKEY: reference(applicationInsightsId, '2015-05-01').InstrumentationKey - REACT_APP_LAYOUT_CONFIG: reactAppLayoutConfig - } - ) - tags : tags - } -} - -resource cosmos 'Microsoft.DocumentDB/databaseAccounts@2022-08-15' existing = { - name: appSettings.AZURE_COSMOSDB_ACCOUNT -} - -resource contributorRoleDefinition 'Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions@2024-05-15' existing = { - parent: cosmos - name: '00000000-0000-0000-0000-000000000002' -} - -resource role 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2022-05-15' = { - parent: cosmos - name: guid(contributorRoleDefinition.id, cosmos.id) - properties: { - principalId: appService.outputs.identityPrincipalId - roleDefinitionId: contributorRoleDefinition.id - scope: cosmos.id - } -} - -resource aiServices 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' existing = { - name: aiServicesName - scope: resourceGroup(existingAIServiceSubscription, existingAIServiceResourceGroup) -} - -resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { - name: keyVaultName -} - -resource keyVaultSecretsUser 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: '4633458b-17de-408a-b874-0445c86b69e6' -} - -resource keyVaultSecretsUserAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(appService.name, keyVault.name, keyVaultSecretsUser.id) - scope: keyVault - properties: { - roleDefinitionId: keyVaultSecretsUser.id - principalId: appService.outputs.identityPrincipalId - principalType: 'ServicePrincipal' - } -} - -resource aiSearch 'Microsoft.Search/searchServices@2024-06-01-preview' existing = { - name: aiSearchName -} - -resource searchIndexDataReader 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: '1407120a-92aa-4202-b7e9-c0e197c71c8f' -} - -resource searchIndexDataReaderAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(appService.name, aiSearch.name, searchIndexDataReader.id) - scope: aiSearch - properties: { - roleDefinitionId: searchIndexDataReader.id - principalId: appService.outputs.identityPrincipalId - principalType: 'ServicePrincipal' - } -} - -resource aiUser 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: '53ca6127-db72-4b80-b1b0-d745d6d5456d' -} - -module existing_aiServicesModule 'existing_foundry_project.bicep' = if (!empty(azureExistingAIProjectResourceId)) { - name: 'existing_foundry_project' - scope: resourceGroup(existingAIServiceSubscription, existingAIServiceResourceGroup) - params: { - aiServicesName: existingAIServicesName - aiProjectName: existingAIProjectName - } -} - -module assignAiUserRoleToAiProject 'deploy_foundry_role_assignment.bicep' = { - name: 'assignAiUserRoleToAiProject' - scope: resourceGroup(existingAIServiceSubscription, existingAIServiceResourceGroup) - params: { - principalId: appService.outputs.identityPrincipalId - roleDefinitionId: aiUser.id - roleAssignmentName: guid(appService.name, aiServices.id, aiUser.id) - aiServicesName: !empty(azureExistingAIProjectResourceId) ? existingAIServicesName : aiServicesName - aiProjectName: !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[10] : '' - enableSystemAssignedIdentity: false - } -} - -@description('Contains App URL.') -output appUrl string = appService.outputs.appUrl - -@description('Contains React App Layout Config.') -output reactAppLayoutConfig string = reactAppLayoutConfig - -@description('Contains AppInsight Instrumentation Key.') -output appInsightInstrumentationKey string = reference(applicationInsightsId, '2015-05-01').InstrumentationKey diff --git a/infra/deploy_container_registry.bicep b/infra/deploy_container_registry.bicep deleted file mode 100644 index 60c7a269e..000000000 --- a/infra/deploy_container_registry.bicep +++ /dev/null @@ -1,50 +0,0 @@ -targetScope = 'resourceGroup' - -@description('Required. Contains Solution Name.') -param environmentName string - -@description('Required. Contains Solution Location.') -param solutionLocation string = resourceGroup().location - -var uniqueId = toLower(uniqueString(subscription().id, environmentName, solutionLocation)) -var solutionName = 'km${padLeft(take(uniqueId, 12), 12, '0')}' -//var abbrs = loadJsonContent('./abbreviations.json') -var containerRegistryName = 'cr${solutionName}' -var containerRegistryNameCleaned = replace(containerRegistryName, '-', '') - -resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' = { - name: containerRegistryName - location: solutionLocation - sku: { - name: 'Premium' - } - properties: { - dataEndpointEnabled: false - networkRuleBypassOptions: 'AzureServices' - networkRuleSet: { - defaultAction: 'Allow' - } - policies: { - quarantinePolicy: { - status: 'disabled' - } - retentionPolicy: { - status: 'enabled' - days: 7 - } - trustPolicy: { - status: 'disabled' - type: 'Notary' - } - } - publicNetworkAccess: 'Enabled' - zoneRedundancy: 'Disabled' - } -} - -@description('Contains Created ACR Name.') -output createdAcrName string = containerRegistryNameCleaned - -@description('Contains Created ACR ID') -output createdAcrId string = containerRegistry.id - \ No newline at end of file diff --git a/infra/deploy_cosmos_db.bicep b/infra/deploy_cosmos_db.bicep deleted file mode 100644 index 5bf23c171..000000000 --- a/infra/deploy_cosmos_db.bicep +++ /dev/null @@ -1,123 +0,0 @@ -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@description('Required. Contains KeyVault Name') -param keyVaultName string - -@description('Required. Contains Account Name') -param accountName string -// var accountName = '${ solutionName }-cosmos' -var databaseName = 'db_conversation_history' -var collectionName = 'conversations' - -var containers = [ - { - name: collectionName - id: collectionName - partitionKey: '/userId' - } -] - -@allowed([ 'GlobalDocumentDB', 'MongoDB', 'Parse' ]) -param kind string = 'GlobalDocumentDB' - -param tags object = {} - -resource cosmos 'Microsoft.DocumentDB/databaseAccounts@2022-08-15' = { - name: accountName - kind: kind - location: solutionLocation - tags: tags - properties: { - consistencyPolicy: { defaultConsistencyLevel: 'Session' } - locations: [ - { - locationName: solutionLocation - failoverPriority: 0 - isZoneRedundant: false - } - ] - databaseAccountOfferType: 'Standard' - enableAutomaticFailover: false - enableMultipleWriteLocations: false - disableLocalAuth: true - apiProperties: (kind == 'MongoDB') ? { serverVersion: '4.0' } : {} - capabilities: [ { name: 'EnableServerless' } ] - } -} - - -resource database 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2022-05-15' = { - name: '${accountName}/${databaseName}' - properties: { - resource: { id: databaseName } - } - - resource list 'containers' = [for container in containers: { - name: container.name - properties: { - resource: { - id: container.id - partitionKey: { paths: [ container.partitionKey ] } - } - options: {} - } - }] - - dependsOn: [ - cosmos - ] -} - -resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { - name: keyVaultName -} - -resource AZURE_COSMOSDB_ACCOUNT 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-COSMOSDB-ACCOUNT' - properties: { - value: cosmos.name - } -} - -resource AZURE_COSMOSDB_ACCOUNT_KEY 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-COSMOSDB-ACCOUNT-KEY' - properties: { - value: cosmos.listKeys().primaryMasterKey - } -} - -resource AZURE_COSMOSDB_DATABASE 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-COSMOSDB-DATABASE' - properties: { - value: databaseName - } -} - -resource AZURE_COSMOSDB_CONVERSATIONS_CONTAINER 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-COSMOSDB-CONVERSATIONS-CONTAINER' - properties: { - value: collectionName - } -} - -resource AZURE_COSMOSDB_ENABLE_FEEDBACK 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-COSMOSDB-ENABLE-FEEDBACK' - properties: { - value: 'True' - } -} - -@description('Contains Cosmos Account Name.') -output cosmosAccountName string = cosmos.name - -@description('Contains Cosmos DB Name.') -output cosmosDatabaseName string = databaseName - -@description('Contains Cosmos Container Name.') -output cosmosContainerName string = collectionName diff --git a/infra/deploy_foundry_role_assignment.bicep b/infra/deploy_foundry_role_assignment.bicep deleted file mode 100644 index f904db7fd..000000000 --- a/infra/deploy_foundry_role_assignment.bicep +++ /dev/null @@ -1,140 +0,0 @@ -@description('Optional. Contains Principle ID.') -param principalId string = '' - -@description('Required. Contains Role Definition ID.') -param roleDefinitionId string - -@description('Optional. Contains Role Assignment Name.') -param roleAssignmentName string = '' - -@description('Required. Contains AI Services Name.') -param aiServicesName string - -@description('Optional. Contains AI Project Name.') -param aiProjectName string = '' - -@description('Optional. Contains AI Location.') -param aiLocation string='' - -@description('Optional. Contains AI Kind.') -param aiKind string='' - -@description('Optional. Contains AI SKU Name.') -param aiSkuName string='' - -@description('Optional. Whether to Enable or Disable System Assigned Identity.') -param enableSystemAssignedIdentity bool = false - -@description('Optional. Contains Custom Sub Domain Name.') -param customSubDomainName string = '' - -@description('Optional. Contains Public Network Access.') -param publicNetworkAccess string = '' - -@description('Optional. Contains Default Network Action.') -param defaultNetworkAction string = '' - -@description('Required. Contains VNET Rules.') -param vnetRules array = [] - -@description('Required. Contains IP Rules.') -param ipRules array = [] - -@description('Required. Contains AI Model Deployments.') -param aiModelDeployments array = [] - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -resource aiServices 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' existing = if (!enableSystemAssignedIdentity) { - name: aiServicesName -} - -resource aiServicesWithIdentity 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' = if (enableSystemAssignedIdentity) { - name: aiServicesName - location: aiLocation - kind: aiKind - sku: { - name: aiSkuName - } - identity: { - type: 'SystemAssigned' - } - properties: { - allowProjectManagement: true - customSubDomainName: customSubDomainName - networkAcls: { - defaultAction: defaultNetworkAction - virtualNetworkRules: vnetRules - ipRules: ipRules - } - publicNetworkAccess: publicNetworkAccess - } - tags : tags -} - -@batchSize(1) -resource aiServicesDeployments 'Microsoft.CognitiveServices/accounts/deployments@2025-04-01-preview' = [for aiModeldeployment in aiModelDeployments: if (!empty(aiModelDeployments)) { - parent: aiServicesWithIdentity - name: aiModeldeployment.name - properties: { - model: { - format: 'OpenAI' - name: aiModeldeployment.model - } - raiPolicyName: aiModeldeployment.raiPolicyName - } - sku:{ - name: aiModeldeployment.sku.name - capacity: aiModeldeployment.sku.capacity - } -}] - -resource aiProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' existing = if (!empty(aiProjectName) && !enableSystemAssignedIdentity) { - name: aiProjectName - parent: aiServices -} - -resource aiProjectWithIdentity 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' = if (!empty(aiProjectName) && enableSystemAssignedIdentity) { - name: aiProjectName - parent: aiServicesWithIdentity - location: aiLocation - identity: { - type: 'SystemAssigned' - } - properties: {} - tags : tags -} - -// Role Assignment to AI Services -resource roleAssignmentToFoundryExisting 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (enableSystemAssignedIdentity) { - name: roleAssignmentName - scope: aiServicesWithIdentity - properties: { - roleDefinitionId: roleDefinitionId - principalId: principalId - principalType: 'ServicePrincipal' - } -} - -resource roleAssignmentToFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (!enableSystemAssignedIdentity) { - name: roleAssignmentName - scope: aiServices - properties: { - roleDefinitionId: roleDefinitionId - principalId: principalId - principalType: 'ServicePrincipal' - } -} - -// ========== Outputs ========== - -output aiServicesPrincipalId string = enableSystemAssignedIdentity - ? aiServicesWithIdentity.identity.principalId - : aiServices.identity.principalId - -output aiProjectPrincipalId string = !empty(aiProjectName) - ? (enableSystemAssignedIdentity - ? aiProjectWithIdentity.identity.principalId - : aiProject.identity.principalId) - : '' diff --git a/infra/deploy_frontend_docker.bicep b/infra/deploy_frontend_docker.bicep deleted file mode 100644 index ab5ee79b1..000000000 --- a/infra/deploy_frontend_docker.bicep +++ /dev/null @@ -1,46 +0,0 @@ -@description('Required. Contains the Image Tag.') -param imageTag string - -@description('Required. Contains ACR Name.') -param acrName string - -@description('Required. Contains Application Insights ID.') -param applicationInsightsId string - -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@secure() -@description('Required. Contains App Settings.') -param appSettings object = {} - -@description('Required. Contains App Service Plan ID.') -param appServicePlanId string - -var imageName = 'DOCKER|${acrName}.azurecr.io/km-app:${imageTag}' -//var name = '${solutionName}-app' -@description('Required. The name of the app service resource within the current resource group scope.') -param name string - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -module appService 'deploy_app_service.bicep' = { - name: '${name}-app-module' - params: { - solutionLocation:solutionLocation - solutionName: name - appServicePlanId: appServicePlanId - appImageName: imageName - appSettings: union( - appSettings, - { - APPINSIGHTS_INSTRUMENTATIONKEY: reference(applicationInsightsId, '2015-05-01').InstrumentationKey - } - ) - tags : tags - } -} - -@description('Contains App URL.') -output appUrl string = appService.outputs.appUrl diff --git a/infra/deploy_index_scripts.bicep b/infra/deploy_index_scripts.bicep deleted file mode 100644 index e45e8349b..000000000 --- a/infra/deploy_index_scripts.bicep +++ /dev/null @@ -1,38 +0,0 @@ -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@description('Required. Contains the Base URL.') -param baseUrl string - -@description('Required. Contains KeyVault Name.') -param keyVaultName string - -@description('Required. Contains ID of ManagedIdentity.') -param managedIdentityResourceId string - -@description('Required. Contains Managed Identity Client ID.') -param managedIdentityClientId string - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -resource create_index 'Microsoft.Resources/deploymentScripts@2023-08-01' = { - kind:'AzureCLI' - name: 'create_search_indexes' - location: solutionLocation - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentityResourceId}' : {} - } - } - properties: { - azCliVersion: '2.52.0' - primaryScriptUri: '${baseUrl}infra/scripts/run_create_index_scripts.sh' - arguments: '${baseUrl} ${keyVaultName} ${managedIdentityClientId}' - timeout: 'PT1H' - retentionInterval: 'PT1H' - cleanupPreference:'OnSuccess' - } - tags : tags -} diff --git a/infra/deploy_keyvault.bicep b/infra/deploy_keyvault.bicep deleted file mode 100644 index 3494db882..000000000 --- a/infra/deploy_keyvault.bicep +++ /dev/null @@ -1,78 +0,0 @@ -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@description('Required. Contains ID of Managed Identity.') -param managedIdentityObjectId string - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -param keyvaultName string - -resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { - name: keyvaultName - location: solutionLocation - properties: { - createMode: 'default' - accessPolicies: [ - { - objectId: managedIdentityObjectId - permissions: { - certificates: [ - 'all' - ] - keys: [ - 'all' - ] - secrets: [ - 'all' - ] - storage: [ - 'all' - ] - } - tenantId: subscription().tenantId - } - ] - enabledForDeployment: true - enabledForDiskEncryption: true - enabledForTemplateDeployment: true - enableRbacAuthorization: true - publicNetworkAccess: 'enabled' - // networkAcls: { - // bypass: 'AzureServices' - // defaultAction: 'Deny' - // } - sku: { - family: 'A' - name: 'standard' - } - softDeleteRetentionInDays: 7 - tenantId: subscription().tenantId - } - tags : tags -} - -@description('This is the built-in Key Vault Administrator role.') -resource kvAdminRole 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = { - scope: resourceGroup() - name: '00482a5a-887f-4fb3-b363-3b7fe8e74483' -} - -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, managedIdentityObjectId, kvAdminRole.id) - properties: { - principalId: managedIdentityObjectId - roleDefinitionId:kvAdminRole.id - principalType: 'ServicePrincipal' - } -} - -@description('Contains KeyVault Name.') -output keyvaultName string = keyvaultName - -@description('Contains KeyVault ID.') -output keyvaultId string = keyVault.id - -@description('Contains KeyVault URI.') -output keyvaultUri string = keyVault.properties.vaultUri diff --git a/infra/deploy_managed_identity.bicep b/infra/deploy_managed_identity.bicep deleted file mode 100644 index ac7048e15..000000000 --- a/infra/deploy_managed_identity.bicep +++ /dev/null @@ -1,62 +0,0 @@ -// ========== Managed Identity ========== // -targetScope = 'resourceGroup' - -@minLength(3) -@maxLength(16) -@description('Required. Contains Solution Name.') -param solutionName string - -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@description('Required. Contains MI Name.') -param miName string - -@description('Optional. The tags to apply to all deployed Azure resources.') -param tags object = {} - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: miName - location: solutionLocation - tags: tags -} - -@description('This is the built-in owner role. See https://docs.microsoft.com/azure/role-based-access-control/built-in-roles#owner') -resource ownerRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = { - scope: resourceGroup() - name: '8e3af657-a8ff-443c-a75c-2fe8c4bcb635' -} - -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, managedIdentity.id, ownerRoleDefinition.id) - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: ownerRoleDefinition.id - principalType: 'ServicePrincipal' - } -} - -resource managedIdentityBackendApp 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: '${solutionName}-backend-app-mi' - location: solutionLocation - tags: { - app: solutionName - location: solutionLocation - } -} - -@description('Contains Managed Identity Object details.') -output managedIdentityOutput object = { - id: managedIdentity.id - objectId: managedIdentity.properties.principalId - clientId: managedIdentity.properties.clientId - name: miName -} - -@description('Contains Managed Identity Backend App Output details..') -output managedIdentityBackendAppOutput object = { - id: managedIdentityBackendApp.id - objectId: managedIdentityBackendApp.properties.principalId - clientId: managedIdentityBackendApp.properties.clientId - name: managedIdentityBackendApp.name -} diff --git a/infra/deploy_sql_db.bicep b/infra/deploy_sql_db.bicep deleted file mode 100644 index 1bcad4c39..000000000 --- a/infra/deploy_sql_db.bicep +++ /dev/null @@ -1,128 +0,0 @@ -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@description('Required. Contains KeyVault Name.') -param keyVaultName string - -@description('Required. Contains Managed Identity Name.') -param managedIdentityName string - -@description('Required. Contains Server Name.') -param serverName string - -@description('Required. Contains SQL DB Name.') -param sqlDBName string - -@description('Required. List of SQL Users.') -param sqlUsers array = [] - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -var location = solutionLocation - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = { - name: managedIdentityName -} - -resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = { - name: serverName - location: location - kind: 'v12.0' - properties: { - publicNetworkAccess: 'Enabled' - version: '12.0' - restrictOutboundNetworkAccess: 'Disabled' - minimalTlsVersion: '1.2' - administrators: { - login: managedIdentityName - sid: managedIdentity.properties.principalId - tenantId: subscription().tenantId - administratorType: 'ActiveDirectory' - azureADOnlyAuthentication: true - } - } - tags : tags -} - -resource firewallRule 'Microsoft.Sql/servers/firewallRules@2023-08-01-preview' = { - name: 'AllowSpecificRange' - parent: sqlServer - properties: { - startIpAddress: '0.0.0.0' - endIpAddress: '255.255.255.255' - } -} - -resource AllowAllWindowsAzureIps 'Microsoft.Sql/servers/firewallRules@2023-08-01-preview' = { - name: 'AllowAllWindowsAzureIps' - parent: sqlServer - properties: { - startIpAddress: '0.0.0.0' - endIpAddress: '0.0.0.0' - } -} - -resource sqlDB 'Microsoft.Sql/servers/databases@2023-08-01-preview' = { - parent: sqlServer - name: sqlDBName - location: location - sku: { - name: 'GP_S_Gen5' - tier: 'GeneralPurpose' - family: 'Gen5' - capacity: 2 - } - kind: 'v12.0,user,vcore,serverless' - properties: { - collation: 'SQL_Latin1_General_CP1_CI_AS' - autoPauseDelay: 60 - minCapacity: 1 - readScale: 'Disabled' - zoneRedundant: false - } - tags : tags -} - -module sqluser 'create-sql-user-and-role.bicep' = [ - for user in sqlUsers: { - name: 'sqluser-${guid(solutionLocation, user.principalId, user.principalName, sqlDB.name, sqlServer.name)}' - params: { - managedIdentityName: managedIdentityName - location: solutionLocation - sqlDatabaseName: sqlDB.name - sqlServerName: sqlServer.name - principalId: user.principalId - principalName: user.principalName - databaseRoles: user.databaseRoles - } - } -] - -resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { - name: keyVaultName -} - -resource sqldbServerEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'SQLDB-SERVER' - properties: { - value: '${serverName}${environment().suffixes.sqlServerHostname}' - } - tags : tags -} - -resource sqldbDatabaseEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'SQLDB-DATABASE' - properties: { - value: sqlDBName - } - tags : tags -} - -@description('Contains SQL Server Name.') -output sqlServerName string = '${serverName}.database.windows.net' - -@description('Contains SQL DB Name.') -output sqlDbName string = sqlDBName diff --git a/infra/deploy_storage_account.bicep b/infra/deploy_storage_account.bicep deleted file mode 100644 index 168e2a805..000000000 --- a/infra/deploy_storage_account.bicep +++ /dev/null @@ -1,160 +0,0 @@ -// ========== Storage Account ========== // -targetScope = 'resourceGroup' - -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@description('Required. Contains Storage Account Name.') -param saName string - -@description('Required. Contains KeyVault Name.') -param keyVaultName string - -@description('Required. Contains Managed Identity Object ID.') -param managedIdentityObjectId string - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -resource storageAccounts_resource 'Microsoft.Storage/storageAccounts@2022-09-01' = { - name: saName - location: solutionLocation - sku: { - name: 'Standard_LRS' - tier: 'Standard' - } - kind: 'StorageV2' - properties: { - minimumTlsVersion: 'TLS1_2' - allowBlobPublicAccess: false - allowSharedKeyAccess: false - isHnsEnabled: true - networkAcls: { - bypass: 'AzureServices' - virtualNetworkRules: [] - ipRules: [] - defaultAction: 'Allow' - } - supportsHttpsTrafficOnly: true - encryption: { - services: { - file: { - keyType: 'Account' - enabled: true - } - blob: { - keyType: 'Account' - enabled: true - } - } - keySource: 'Microsoft.Storage' - } - accessTier: 'Hot' - } - tags : tags -} - -resource storageAccounts_default 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01' = { - parent: storageAccounts_resource - name: 'default' - properties: { - cors: { - corsRules: [] - } - deleteRetentionPolicy: { - allowPermanentDelete: false - enabled: false - } - } -} - - -resource storageAccounts_default_data 'Microsoft.Storage/storageAccounts/blobServices/containers@2022-09-01' = { - parent: storageAccounts_default - name: 'data' - properties: { - defaultEncryptionScope: '$account-encryption-key' - denyEncryptionScopeOverride: false - publicAccess: 'None' - } -} - -// resource storageAccounts_default_input 'Microsoft.Storage/storageAccounts/blobServices/containers@2022-09-01' = { -// parent: storageAccounts_default -// name: 'graphrag' -// properties: { -// defaultEncryptionScope: '$account-encryption-key' -// denyEncryptionScopeOverride: false -// publicAccess: 'None' -// } -// dependsOn: [ -// storageAccounts_resource -// ] -// } - -@description('This is the built-in Storage Blob Data Contributor.') -resource blobDataContributor 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = { - scope: resourceGroup() - name: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' -} - -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, managedIdentityObjectId, blobDataContributor.id) - properties: { - principalId: managedIdentityObjectId - roleDefinitionId:blobDataContributor.id - principalType: 'ServicePrincipal' - } -} - - -var storageAccountKeys = listKeys(storageAccounts_resource.id, '2021-04-01') -// var storageAccountString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccounts_resource.name};AccountKey=${storageAccounts_resource.listKeys().keys[0].value};EndpointSuffix=${environment().suffixes.storage}' - -resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { - name: keyVaultName -} - -resource adlsAccountNameEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'ADLS-ACCOUNT-NAME' - properties: { - value: saName - } - tags : tags -} - -resource adlsAccountContainerEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'ADLS-ACCOUNT-CONTAINER' - properties: { - value: 'data' - } - tags : tags -} - -resource adlsAccountKeyEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'ADLS-ACCOUNT-KEY' - properties: { - value: storageAccountKeys.keys[0].value - } - tags : tags -} - -@description('Contains Storage Name.') -output storageName string = saName - -@description('Contains Storage Container Name.') -output storageContainer string = 'data' -// output storageAccountOutput object = { -// id: storageAccounts_resource.id -// name: saName -// uri: storageAccounts_resource.properties.primaryEndpoints.web -// dfs: storageAccounts_resource.properties.primaryEndpoints.dfs -// storageAccountName:saName -// key:storageAccountKeys.keys[0].value -// connectionString:storageAccountString -// dataContainer:storageAccounts_default_data.name -// } - diff --git a/infra/deploy_upload_files_script.bicep b/infra/deploy_upload_files_script.bicep deleted file mode 100644 index 078a00efc..000000000 --- a/infra/deploy_upload_files_script.bicep +++ /dev/null @@ -1,37 +0,0 @@ -@description('Required. Specifies the location for resources.') -param solutionLocation string - -@description('Required. Contains Base URL.') -param baseUrl string - -@description('Required. Contains Managed Identity Resource ID.') -param managedIdentityResourceId string - -@description('Required. Contains Managed Identity Client ID.') -param managedIdentityClientId string - -@description('Required. Contains Storage Account Name.') -param storageAccountName string - -@description('Required. Contains COntainer Name.') -param containerName string - -resource copy_demo_Data 'Microsoft.Resources/deploymentScripts@2023-08-01' = { - kind:'AzureCLI' - name: 'copy_demo_Data' - location: solutionLocation - identity:{ - type:'UserAssigned' - userAssignedIdentities: { - '${managedIdentityResourceId}' : {} - } - } - properties: { - azCliVersion: '2.52.0' - primaryScriptUri: '${baseUrl}infra/scripts/copy_kb_files.sh' - arguments: '${storageAccountName} ${containerName} ${baseUrl} ${managedIdentityClientId}' - timeout: 'PT1H' - retentionInterval: 'PT1H' - cleanupPreference:'OnSuccess' - } -} diff --git a/infra/existing_foundry_project.bicep b/infra/existing_foundry_project.bicep deleted file mode 100644 index c9dbd1e46..000000000 --- a/infra/existing_foundry_project.bicep +++ /dev/null @@ -1,56 +0,0 @@ -@description('Required. Name of the existing Azure AI Services account') -param aiServicesName string - -@description('Required. Name of the existing AI Project under the AI Services account') -param aiProjectName string - -resource aiServices 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' existing = { - name: aiServicesName -} - -resource aiProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' existing = { - name: aiProjectName - parent: aiServices -} - - - -// Outputs: AI Services Account -@description('Contains Service Location.') -output location string = aiServices.location - -@description('Contains SKU Name.') -output skuName string = aiServices.sku.name - -@description('Contains Kind of Service.') -output kind string = aiServices.kind - -@description('Specifies whether to Enable or Disable Project Management.') -output allowProjectManagement bool = aiServices.properties.allowProjectManagement - -@description('Contains Custom Sub Domain Name.') -output customSubDomainName string = aiServices.properties.customSubDomainName - -@description('Contains Properties of Public Network Access.') -output publicNetworkAccess string = aiServices.properties.publicNetworkAccess - -@description('Contains Default Network Action.') -output defaultNetworkAction string = aiServices.properties.networkAcls.defaultAction - -@description('Contains the IP Rules.') -output ipRules array = aiServices.properties.networkAcls.ipRules - -@description('Contains VNET Rules.') -output vnetRules array = aiServices.properties.networkAcls.virtualNetworkRules - -// Outputs: AI Project -@description('Contains Location of Project.') -output projectLocation string = aiProject.location - -@description('Contains Kind of Project.') -output projectKind string = aiProject.kind - -@description('Contains Project Provisioning State.') -output projectProvisioningState string = aiProject.properties.provisioningState -// output projectDisplayName string = aiProject.properties.displayName -// output projectDescription string = aiProject.properties.description diff --git a/infra/main.parameters.json b/infra/main.parameters.json index ef60df440..633fd033e 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -18,16 +18,16 @@ "value": "${AZURE_ENV_OPENAI_LOCATION}" }, "gptModelDeploymentType": { - "value": "${AZURE_ENV_MODEL_DEPLOYMENT_TYPE}" + "value": "${AZURE_OPENAI_MODEL_DEPLOYMENT_TYPE}" }, "gptModelName": { - "value": "${AZURE_ENV_MODEL_NAME}" + "value": "${AZURE_OPENAI_DEPLOYMENT_MODEL}" }, "gptModelVersion": { - "value": "${AZURE_ENV_MODEL_VERSION}" + "value": "${AZURE_OPENAI_API_VERSION}" }, "gptModelCapacity": { - "value": "${AZURE_ENV_MODEL_CAPACITY}" + "value": "${AZURE_OPENAI_DEPLOYMENT_MODEL_CAPACITY}" }, "embeddingModel": { "value": "${AZURE_OPENAI_EMBEDDING_MODEL}" @@ -36,10 +36,10 @@ "value": "${AZURE_OPENAI_EMBEDDING_MODEL_CAPACITY}" }, "backendContainerImageTag": { - "value": "${AZURE_ENV_IMAGE_TAG=latest_waf}" + "value": "${AZURE_ENV_IMAGETAG=latest_waf}" }, "frontendContainerImageTag": { - "value": "${AZURE_ENV_IMAGE_TAG=latest_waf}" + "value": "${AZURE_ENV_IMAGETAG=latest_waf}" }, "enableTelemetry": { "value": "${AZURE_ENV_ENABLE_TELEMETRY}" @@ -48,7 +48,7 @@ "value": "${AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID}" }, "existingAiFoundryAiProjectResourceId": { - "value": "${AZURE_ENV_FOUNDRY_PROJECT_ID}" + "value": "${AZURE_EXISTING_AI_PROJECT_RESOURCE_ID}" } } } \ No newline at end of file diff --git a/infra/main.waf.parameters.json b/infra/main.waf.parameters.json index ac68c338d..1b4493cd6 100644 --- a/infra/main.waf.parameters.json +++ b/infra/main.waf.parameters.json @@ -18,16 +18,16 @@ "value": "${AZURE_ENV_OPENAI_LOCATION}" }, "gptModelDeploymentType": { - "value": "${AZURE_ENV_MODEL_DEPLOYMENT_TYPE}" + "value": "${AZURE_OPENAI_MODEL_DEPLOYMENT_TYPE}" }, "gptModelName": { - "value": "${AZURE_ENV_MODEL_NAME}" + "value": "${AZURE_OPENAI_DEPLOYMENT_MODEL}" }, "gptModelVersion": { - "value": "${AZURE_ENV_MODEL_VERSION}" + "value": "${AZURE_OPENAI_API_VERSION}" }, "gptModelCapacity": { - "value": "${AZURE_ENV_MODEL_CAPACITY}" + "value": "${AZURE_OPENAI_DEPLOYMENT_MODEL_CAPACITY}" }, "embeddingModel": { "value": "${AZURE_OPENAI_EMBEDDING_MODEL}" @@ -36,10 +36,10 @@ "value": "${AZURE_OPENAI_EMBEDDING_MODEL_CAPACITY}" }, "backendContainerImageTag": { - "value": "${AZURE_ENV_IMAGE_TAG=latest_waf}" + "value": "${AZURE_ENV_IMAGETAG=latest_waf}" }, "frontendContainerImageTag": { - "value": "${AZURE_ENV_IMAGE_TAG=latest_waf}" + "value": "${AZURE_ENV_IMAGETAG=latest_waf}" }, "enableTelemetry": { "value": "${AZURE_ENV_ENABLE_TELEMETRY}" @@ -48,7 +48,7 @@ "value": "${AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID}" }, "existingAiFoundryAiProjectResourceId": { - "value": "${AZURE_ENV_FOUNDRY_PROJECT_ID}" + "value": "${AZURE_EXISTING_AI_PROJECT_RESOURCE_ID}" }, "enableMonitoring": { "value": true