Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ environment:
name: conversation-knowledge-mining
location: eastus
name: conversation-knowledge-mining

requiredVersions:
azd: ">= 1.15.0"

metadata:
template: conversation-knowledge-mining@1.0

Expand Down
2 changes: 1 addition & 1 deletion documents/DeploymentGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ If you're not using one of the above options for opening the project, then you'l

1. Make sure the following tools are installed:
- [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.5) <small>(v7.0+)</small> - available for Windows, macOS, and Linux.
- [Azure Developer CLI (azd)](https://aka.ms/install-azd)
- [Azure Developer CLI (azd)](https://aka.ms/install-azd) <small>(v1.15.0+)</small> - version
- [Python 3.9+](https://www.python.org/downloads/)
- [Docker Desktop](https://www.docker.com/products/docker-desktop/)
- [Git](https://git-scm.com/downloads)
Expand Down
34 changes: 30 additions & 4 deletions infra/deploy_ai_foundry.bicep
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Creates Azure dependent resources for Azure AI studio
param solutionName string
param solutionLocation string
param keyVaultName string
param keyVaultName string=''
param cuLocation string
param deploymentType string
param gptModelName string
Expand All @@ -10,7 +10,7 @@ param azureOpenAIApiVersion string
param gptDeploymentCapacity int
param embeddingModel string
param embeddingDeploymentCapacity int
param managedIdentityObjectId string
param managedIdentityObjectId string=''
param existingLogAnalyticsWorkspaceId string = ''
param azureExistingAIProjectResourceId string = ''

Expand Down Expand Up @@ -116,6 +116,15 @@ resource aiServices 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' =
}
}

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
Expand Down Expand Up @@ -225,6 +234,7 @@ 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
Expand All @@ -234,7 +244,6 @@ resource assignFoundryRoleToMI 'Microsoft.Authorization/roleAssignments@2022-04-
principalType: 'ServicePrincipal'
}
}

module assignFoundryRoleToMIExisting 'deploy_foundry_role_assignment.bicep' = if (!empty(azureExistingAIProjectResourceId)) {
name: 'assignFoundryRoleToMI'
scope: resourceGroup(existingAIServiceSubscription, existingAIServiceResourceGroup)
Expand All @@ -244,6 +253,15 @@ module assignFoundryRoleToMIExisting 'deploy_foundry_role_assignment.bicep' = if
aiServicesName: !empty(azureExistingAIProjectResourceId) ? existingAIServicesName : aiServicesName
aiProjectName: !empty(azureExistingAIProjectResourceId) ? existingAIProjectName : aiProjectName
principalId: managedIdentityObjectId
aiLocation: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.location : solutionLocation
aiKind: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.kind : 'AIServices'
aiSkuName: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.skuName : 'S0'
customSubDomainName: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.customSubDomainName : aiServicesName
publicNetworkAccess: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.publicNetworkAccess : 'Enabled'
enableSystemAssignedIdentity: true
defaultNetworkAction: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.defaultNetworkAction : 'Allow'
vnetRules: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.vnetRules : []
ipRules: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.ipRules : []
}
}

Expand All @@ -270,6 +288,15 @@ module assignOpenAIRoleToAISearch 'deploy_foundry_role_assignment.bicep' = {
aiServicesName: !empty(azureExistingAIProjectResourceId) ? existingAIServicesName : aiServicesName
aiProjectName: !empty(azureExistingAIProjectResourceId) ? existingAIProjectName : aiProjectName
principalId: aiSearch.identity.principalId
aiLocation: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.location : solutionLocation
aiKind: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.kind : 'AIServices'
aiSkuName: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.skuName : 'S0'
customSubDomainName: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.customSubDomainName : aiServicesName
publicNetworkAccess: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.publicNetworkAccess : 'Enabled'
enableSystemAssignedIdentity: true
defaultNetworkAction: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.defaultNetworkAction : 'Allow'
vnetRules: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.vnetRules : []
ipRules: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.ipRules : []
}
}

Expand Down Expand Up @@ -470,7 +497,6 @@ resource azureLocatioEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview
value: solutionLocation
}
}

output keyvaultName string = keyvaultName
output keyvaultId string = keyVault.id
output aiServicesTarget string = !empty(existingOpenAIEndpoint) ? existingOpenAIEndpoint : aiServices.properties.endpoints['OpenAI Language Model Instance API'] //aiServices_m.properties.endpoint
Expand Down
21 changes: 21 additions & 0 deletions infra/deploy_backend_docker.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ param aiServicesName string
param useLocalBuild string
param azureExistingAIProjectResourceId string = ''
param aiSearchName string
param aideploymentsLocation string
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
Expand Down Expand Up @@ -165,6 +167,15 @@ 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)
Expand All @@ -173,6 +184,16 @@ module assignAiUserRoleToAiProject 'deploy_foundry_role_assignment.bicep' = {
roleDefinitionId: aiUser.id
roleAssignmentName: guid(appService.name, aiServices.id, aiUser.id)
aiServicesName: !empty(azureExistingAIProjectResourceId) ? existingAIServicesName : aiServicesName
aiProjectName: !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[10] : ''
aiLocation: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.location : aideploymentsLocation
aiKind: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.kind : 'AIServices'
aiSkuName: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.skuName : 'S0'
customSubDomainName: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.customSubDomainName : aiServicesName
publicNetworkAccess: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.publicNetworkAccess : 'Enabled'
enableSystemAssignedIdentity: true
defaultNetworkAction: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.defaultNetworkAction : 'Allow'
vnetRules: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.vnetRules : []
ipRules: !empty(azureExistingAIProjectResourceId) ? existing_aiServicesModule.outputs.ipRules : []
}
}

Expand Down
43 changes: 40 additions & 3 deletions infra/deploy_foundry_role_assignment.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,52 @@ param roleDefinitionId string
param roleAssignmentName string = ''
param aiServicesName string
param aiProjectName string = ''
param aiLocation string=''
param aiKind string=''
param aiSkuName string=''
param enableSystemAssignedIdentity bool = true
param customSubDomainName string = ''
param publicNetworkAccess string = ''
param defaultNetworkAction string
param vnetRules array = []
param ipRules array = []

resource aiServices 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' existing = {
// AI Services with Identity (enabled only if flag is true)
resource aiServices '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

}
}

resource aiProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' existing = if (!empty(aiProjectName)) {
// AI Project with Identity (only if name provided and flag is true)
resource aiProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' = if (!empty(aiProjectName) && enableSystemAssignedIdentity) {
name: aiProjectName
parent: aiServices
location: aiLocation
identity: {
type: 'SystemAssigned'
}
properties: {}
}

// Role Assignment to AI Services
resource roleAssignmentToFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: roleAssignmentName
scope: aiServices
Expand All @@ -22,5 +58,6 @@ resource roleAssignmentToFoundry 'Microsoft.Authorization/roleAssignments@2022-0
}
}

// Outputs
output aiServicesPrincipalId string = aiServices.identity.principalId
output aiProjectPrincipalId string = !empty(aiProjectName) ? aiProject.identity.principalId : ''
output aiProjectPrincipalId string = !empty(aiProjectName) ? aiProject.identity.principalId : ''
35 changes: 35 additions & 0 deletions infra/existing_foundry_project.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@description('Name of the existing Azure AI Services account')
param aiServicesName string

@description('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
output location string = aiServices.location
output skuName string = aiServices.sku.name
output kind string = aiServices.kind
output allowProjectManagement bool = aiServices.properties.allowProjectManagement
output customSubDomainName string = aiServices.properties.customSubDomainName
output publicNetworkAccess string = aiServices.properties.publicNetworkAccess
output defaultNetworkAction string = aiServices.properties.networkAcls.defaultAction
output ipRules array = aiServices.properties.networkAcls.ipRules
output vnetRules array = aiServices.properties.networkAcls.virtualNetworkRules

// Outputs: AI Project

output projectLocation string = aiProject.location
output projectKind string = aiProject.kind
output projectProvisioningState string = aiProject.properties.provisioningState
// output projectDisplayName string = aiProject.properties.displayName
// output projectDescription string = aiProject.properties.description
3 changes: 2 additions & 1 deletion infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ module aifoundry 'deploy_ai_foundry.bicep' = {
embeddingDeploymentCapacity: embeddingDeploymentCapacity
managedIdentityObjectId: managedIdentityModule.outputs.managedIdentityOutput.objectId
existingLogAnalyticsWorkspaceId: existingLogAnalyticsWorkspaceId
azureExistingAIProjectResourceId: azureExistingAIProjectResourceId
azureExistingAIProjectResourceId: azureExistingAIProjectResourceId

}
scope: resourceGroup(resourceGroup().name)
Expand Down Expand Up @@ -219,6 +219,7 @@ module backend_docker 'deploy_backend_docker.bicep' = {
params: {
name: 'api-${solutionPrefix}'
solutionLocation: solutionLocation
aideploymentsLocation: aiDeploymentsLocation
imageTag: imageTag
acrName: acrName
appServicePlanId: hostingplan.outputs.name
Expand Down
Loading