Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"aiHubName": {
"value": "hub-demo"
},
"aiHubFriendlyName": {
"value": "Agents Hub resource"
},
"aiHubDescription": {
"value": "This is an example AI resource for use in Azure AI Studio."
},
"aiProjectName": {
"value": "project-demo"
},
"aiProjectFriendlyName": {
"value": "Agents Project resource"
},
"aiProjectDescription": {
"value": "This is an example AI Project resource for use in Azure AI Studio."
},
"aiSearchName": {
"value": "agent-ai-search"
},
"capabilityHostName": {
"value": "caphost1"
},
"storageName": {
"value": "agent-storage"
},
"aiServicesName": {
"value": "agent-ai-services"
},
"modelName": {
"value": "gpt-4o-mini"
},
"modelFormat": {
"value": "OpenAI"
},
"modelVersion": {
"value": "2024-07-18"
},
"modelSkuName": {
"value": "GlobalStandard"
},
"modelCapacity": {
"value": 50
},
"modelLocation": {
"value": "eastus"
},
"aiServiceAccountResourceId": {
"value": ""
},
"aiSearchServiceResourceId": {
"value": ""
},
"aiStorageAccountResourceId":{
"value": ""
},
"aiServiceKind": {
"value": "AIServices"
},
"deploymentTimestamp": {
"value": "vhvb1989"
}
}
}

219 changes: 219 additions & 0 deletions scenarios/Agents/setup/standard-agent-UMI/main.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
// Execute this main file to deploy Enterprise Standard Agent setup resources

module userDefinedTypes 'modules-standard/types.bicep' = {}

// Parameters
@minLength(2)
@maxLength(12)
@description('Name for the AI resource and used to derive name of dependent resources.')
param aiHubName string = 'hub-demo'

@description('Friendly name for your Hub resource')
param aiHubFriendlyName string = 'Agents Hub resource'

@description('Description of your Azure AI resource displayed in AI studio')
param aiHubDescription string = 'This is an example AI resource for use in Azure AI Studio.'

@description('Name for the AI project resources.')
param aiProjectName string = 'project-demo'

@description('Friendly name for your Azure AI resource')
param aiProjectFriendlyName string = 'Agents Project resource'

@description('Description of your Azure AI resource displayed in AI studio')
param aiProjectDescription string = 'This is an example AI Project resource for use in Azure AI Studio.'

@description('Azure region used for the deployment of all resources.')
param location string = resourceGroup().location

@description('Set of tags to apply to all resources.')
param tags object = {}

@description('Name of the Azure AI Search account')
param aiSearchName string = 'agent-ai-search'

@description('Name for capabilityHost.')
param capabilityHostName string = 'caphost1'

@description('Name of the storage account')
param storageName string = 'agent-storage'

@description('Name of the Azure AI Services account')
param aiServicesName string = 'agent-ai-services'

@description('Model name for deployment')
param modelName string = 'gpt-4o-mini'

@description('Model format for deployment')
param modelFormat string = 'OpenAI'

@description('Model version for deployment')
param modelVersion string = '2024-07-18'

@description('Model deployment SKU name')
param modelSkuName string = 'GlobalStandard'

@description('Model deployment capacity')
param modelCapacity int = 50

@description('Model deployment location. If you want to deploy an Azure AI resource/model in different location than the rest of the resources created.')
param modelLocation string = 'eastus'

@description('AI Service Account kind: either AzureOpenAI or AIServices')
param aiServiceKind string = 'AIServices'

@description('The AI Service Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created.')
param aiServiceAccountResourceId string = ''

@description('The Ai Search Service full ARM Resource ID. This is an optional field, and if not provided, the resource will be created.')
param aiSearchServiceResourceId string = ''

@description('The Ai Storage Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created.')
param aiStorageAccountResourceId string = ''

@description('The User Assigned Identity name (within the same resource group) for AI cognitive services. This is an optional field, and if not provided, the resource will be created.')
param userManagedIdentityName string = ''

// Variables
var name = toLower('${aiHubName}')
var projectName = toLower('${aiProjectName}')

// Create a short, unique suffix, that will be unique to each resource group
// var uniqueSuffix = substring(uniqueString(resourceGroup().id), 0, 4)
param deploymentTimestamp string = utcNow('yyyyMMddHHmmss')
var uniqueSuffix = substring(uniqueString('${resourceGroup().id}-${deploymentTimestamp}'), 0, 4)

var aiServiceExists = aiServiceAccountResourceId != ''
var acsExists = aiSearchServiceResourceId != ''

var aiServiceParts = split(aiServiceAccountResourceId, '/')
var aiServiceAccountSubscriptionId = aiServiceExists ? aiServiceParts[2] : subscription().subscriptionId
var aiServiceAccountResourceGroupName = aiServiceExists ? aiServiceParts[4] : resourceGroup().name

var acsParts = split(aiSearchServiceResourceId, '/')
var aiSearchServiceSubscriptionId = acsExists ? acsParts[2] : subscription().subscriptionId
var aiSearchServiceResourceGroupName = acsExists ? acsParts[4] : resourceGroup().name

var aiServicesUserAssignedIdentityExists = userManagedIdentityName != ''

resource aiExistingServicesUserManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2024-11-30' existing = if (aiServicesUserAssignedIdentityExists) {
name: userManagedIdentityName
}

resource aiServicesUserManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2024-11-30' = if (!aiServicesUserAssignedIdentityExists) {
name: 'umi-${projectName}-${uniqueSuffix}'
location: location
tags: tags
}

var umi = {
id: aiServicesUserAssignedIdentityExists ? aiExistingServicesUserManagedIdentity.id : aiServicesUserManagedIdentity.id
principalId: aiServicesUserAssignedIdentityExists ? aiExistingServicesUserManagedIdentity.properties.principalId : aiServicesUserManagedIdentity.properties.principalId
}

// Dependent resources for the Azure Machine Learning workspace
module aiDependencies 'modules-standard/standard-dependent-resources.bicep' = {
name: 'dependencies-${name}-${uniqueSuffix}-deployment'
params: {
location: location
storageName: '${storageName}${uniqueSuffix}'
keyvaultName: 'kv-${name}-${uniqueSuffix}'
aiServicesName: '${aiServicesName}${uniqueSuffix}'
aiSearchName: '${aiSearchName}-${uniqueSuffix}'
tags: tags

// Model deployment parameters
modelName: modelName
modelFormat: modelFormat
modelVersion: modelVersion
modelSkuName: modelSkuName
modelCapacity: modelCapacity
modelLocation: modelLocation

aiServiceAccountResourceId: aiServiceAccountResourceId
aiSearchServiceResourceId: aiSearchServiceResourceId
aiStorageAccountResourceId: aiStorageAccountResourceId

userAssignedIdentity: umi
}
}

module aiHub 'modules-standard/standard-ai-hub.bicep' = {
name: '${name}-${uniqueSuffix}-deployment'
params: {
userAssignedIdentity: umi

// workspace organization
aiHubName: '${name}-${uniqueSuffix}'
aiHubFriendlyName: aiHubFriendlyName
aiHubDescription: aiHubDescription
location: location
tags: tags

aiSearchName: aiDependencies.outputs.aiSearchName
aiSearchId: aiDependencies.outputs.aisearchID
aiSearchServiceResourceGroupName: aiDependencies.outputs.aiSearchServiceResourceGroupName
aiSearchServiceSubscriptionId: aiDependencies.outputs.aiSearchServiceSubscriptionId

aiServicesName: aiDependencies.outputs.aiServicesName
aiServiceKind: aiServiceKind
aiServicesId: aiDependencies.outputs.aiservicesID
aiServicesTarget: aiDependencies.outputs.aiservicesTarget
aiServiceAccountResourceGroupName:aiDependencies.outputs.aiServiceAccountResourceGroupName
aiServiceAccountSubscriptionId:aiDependencies.outputs.aiServiceAccountSubscriptionId

keyVaultId: aiDependencies.outputs.keyvaultId
storageAccountId: aiDependencies.outputs.storageId
}
}


module aiProject 'modules-standard/standard-ai-project.bicep' = {
name: '${projectName}-${uniqueSuffix}-deployment'
params: {
// workspace organization
aiProjectName: '${projectName}-${uniqueSuffix}'
aiProjectFriendlyName: aiProjectFriendlyName
aiProjectDescription: aiProjectDescription
location: location
tags: tags
aiHubId: aiHub.outputs.aiHubID
userAssignedIdentity: umi
}
}

module aiServiceRoleAssignments 'modules-standard/ai-service-role-assignments.bicep' = {
name: 'ai-service-role-assignments-${projectName}-${uniqueSuffix}-deployment'
scope: resourceGroup(aiServiceAccountSubscriptionId, aiServiceAccountResourceGroupName)
params: {
aiServicesName: aiDependencies.outputs.aiServicesName
aiProjectPrincipalId: aiProject.outputs.aiProjectPrincipalId
aiProjectId: aiProject.outputs.aiProjectResourceId
}
}

module aiSearchRoleAssignments 'modules-standard/ai-search-role-assignments.bicep' = {
name: 'ai-search-role-assignments-${projectName}-${uniqueSuffix}-deployment'
scope: resourceGroup(aiSearchServiceSubscriptionId, aiSearchServiceResourceGroupName)
params: {
aiSearchName: aiDependencies.outputs.aiSearchName
aiProjectPrincipalId: aiProject.outputs.aiProjectPrincipalId
aiProjectId: aiProject.outputs.aiProjectResourceId
}
}

module addCapabilityHost 'modules-standard/add-capability-host.bicep' = {
name: 'capabilityHost-configuration--${uniqueSuffix}-deployment'
params: {
capabilityHostName: '${uniqueSuffix}-${capabilityHostName}'
aiHubName: aiHub.outputs.aiHubName
aiProjectName: aiProject.outputs.aiProjectName
acsConnectionName: aiHub.outputs.acsConnectionName
aoaiConnectionName: aiHub.outputs.aoaiConnectionName
}
dependsOn: [
aiSearchRoleAssignments,aiServiceRoleAssignments
]
}

output PROJECT_CONNECTION_STRING string = aiProject.outputs.projectConnectionString
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@description('AI hub name')
param aiHubName string

@description('AI project name')
param aiProjectName string

@description('Name for ACS connection.')
param acsConnectionName string

@description('Name for ACS connection.')
param aoaiConnectionName string

@description('Name for capabilityHost.')
param capabilityHostName string

var storageConnections = ['${aiProjectName}/workspaceblobstore']
var aiSearchConnection = ['${acsConnectionName}']
var aiServiceConnections = ['${aoaiConnectionName}']

resource aiHub 'Microsoft.MachineLearningServices/workspaces@2024-10-01-preview' existing = {
name: aiHubName
}

resource aiProject 'Microsoft.MachineLearningServices/workspaces@2024-10-01-preview' existing = {
name: aiProjectName
}

#disable-next-line BCP081
resource hubCapabilityHost 'Microsoft.MachineLearningServices/workspaces/capabilityHosts@2024-10-01-preview' = {
name: '${aiHubName}-${capabilityHostName}'
parent: aiHub
properties: {
capabilityHostKind: 'Agents'
}
}

#disable-next-line BCP081
resource projectCapabilityHost 'Microsoft.MachineLearningServices/workspaces/capabilityHosts@2024-10-01-preview' = {
name: '${aiProjectName}-${capabilityHostName}'
parent: aiProject
properties: {
capabilityHostKind: 'Agents'
aiServicesConnections: aiServiceConnections
vectorStoreConnections: aiSearchConnection
storageConnections: storageConnections
}
dependsOn: [
hubCapabilityHost
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Assigns the necessary roles to the AI project

@description('Name of the AI Search resource')
param aiSearchName string

@description('Principal ID of the AI project')
param aiProjectPrincipalId string

@description('Resource ID of the AI project')
param aiProjectId string

resource searchService 'Microsoft.Search/searchServices@2024-06-01-preview' existing = {
name: aiSearchName
scope: resourceGroup()
}

// search roles
resource searchIndexDataContributorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
name: '8ebe5a00-799e-43f5-93ac-243d3dce84a7'
scope: resourceGroup()
}

resource searchIndexDataContributorAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: searchService
name: guid(aiProjectId, searchIndexDataContributorRole.id, searchService.id)
properties: {
principalId: aiProjectPrincipalId
roleDefinitionId: searchIndexDataContributorRole.id
principalType: 'ServicePrincipal'
}
}

resource searchServiceContributorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
name: '7ca78c08-252a-4471-8644-bb5ff32d4ba0'
scope: resourceGroup()
}

resource searchServiceContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: searchService
name: guid(aiProjectId, searchServiceContributorRole.id, searchService.id)
properties: {
principalId: aiProjectPrincipalId
roleDefinitionId: searchServiceContributorRole.id
principalType: 'ServicePrincipal'
}
}
Loading
Loading