|
| 1 | +targetScope = 'resourceGroup' |
| 2 | + |
| 3 | +@description('This is the base name for each Azure resource name (6-8 chars)') |
| 4 | +@minLength(6) |
| 5 | +@maxLength(8) |
| 6 | +param baseName string |
| 7 | + |
| 8 | +@description('The existing Agent version to target by the Foundry AI Agent Service application deployment.') |
| 9 | +@minLength(1) |
| 10 | +param agentVersion string = '1' |
| 11 | + |
| 12 | +// ---- Existing resources ---- |
| 13 | + |
| 14 | +// Storage Blob Data Owner Role |
| 15 | +resource storageBlobDataOwnerRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { |
| 16 | + name: 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b' |
| 17 | + scope: subscription() |
| 18 | +} |
| 19 | + |
| 20 | +// Storage Blob Data Contributor |
| 21 | +resource storageBlobDataContributorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { |
| 22 | + name: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' |
| 23 | + scope: subscription() |
| 24 | +} |
| 25 | + |
| 26 | +// Cosmos DB Account Operator Role |
| 27 | +resource cosmosDbOperatorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { |
| 28 | + name: '230815da-be43-4aae-9cb4-875f7bd000aa' |
| 29 | + scope: subscription() |
| 30 | +} |
| 31 | + |
| 32 | +@description('Existing Azure Cosmos DB account. Will be assigning Data Contributor role to the Foundry project\'s identity.') |
| 33 | +resource cosmosDbAccount 'Microsoft.DocumentDB/databaseAccounts@2024-12-01-preview' existing = { |
| 34 | + name: 'cdb-ai-agent-threads-${baseName}' |
| 35 | + |
| 36 | + @description('Built-in Cosmos DB Data Contributor role that can be assigned to Entra identities to grant data access on a Cosmos DB database.') |
| 37 | + resource dataContributorRole 'sqlRoleDefinitions' existing = { |
| 38 | + name: '00000000-0000-0000-0000-000000000002' |
| 39 | + } |
| 40 | +} |
| 41 | + |
| 42 | +resource azureAISearchServiceContributorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { |
| 43 | + name: '7ca78c08-252a-4471-8644-bb5ff32d4ba0' |
| 44 | + scope: subscription() |
| 45 | +} |
| 46 | + |
| 47 | +resource azureAISearchIndexDataContributorRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { |
| 48 | + name: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' |
| 49 | + scope: subscription() |
| 50 | +} |
| 51 | + |
| 52 | +resource agentStorageAccount 'Microsoft.Storage/storageAccounts@2025-06-01' existing = { |
| 53 | + name: 'stagent${baseName}' |
| 54 | +} |
| 55 | + |
| 56 | +resource azureAiSearchService 'Microsoft.Search/searchServices@2025-02-01-preview' existing = { |
| 57 | + name: 'ais-ai-agent-vector-store-${baseName}' |
| 58 | +} |
| 59 | + |
| 60 | +@description('The internal ID of the project is used in the Azure Storage blob containers and in the Cosmos DB collections.') |
| 61 | +#disable-next-line BCP053 |
| 62 | +var workspaceId = foundry::project.properties.internalId |
| 63 | +var workspaceIdAsGuid = '${substring(workspaceId, 0, 8)}-${substring(workspaceId, 8, 4)}-${substring(workspaceId, 12, 4)}-${substring(workspaceId, 16, 4)}-${substring(workspaceId, 20, 12)}' |
| 64 | + |
| 65 | +var scopeAllContainers = '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.DocumentDB/databaseAccounts/${cosmosDbAccount.name}/dbs/enterprise_memory' |
| 66 | + |
| 67 | +// ---- New resources ---- |
| 68 | + |
| 69 | +@description('Existing Foundry account.') |
| 70 | +resource foundry 'Microsoft.CognitiveServices/accounts@2025-10-01-preview' existing = { |
| 71 | + name: 'aif${baseName}' |
| 72 | + |
| 73 | + @description('Existing Foundry project. The application and deployment will be created as a child resource of this project.') |
| 74 | + resource project 'projects' existing = { |
| 75 | + name: 'projchat' |
| 76 | + |
| 77 | + @description('Create agent application in Foundry Agent Service.') |
| 78 | + resource application 'applications' = { |
| 79 | + name: 'appchat' |
| 80 | + properties: { |
| 81 | + agents: [ |
| 82 | + { |
| 83 | + agentName: 'baseline-chatbot-agent' |
| 84 | + } |
| 85 | + ] |
| 86 | + #disable-next-line BCP078 |
| 87 | + authorizationPolicy: { |
| 88 | + authorizationScheme: 'Default' |
| 89 | + } |
| 90 | + displayName: 'Example of an Agent Application that exposes a Foundry agent chat interface through a service endpoint' |
| 91 | + trafficRoutingPolicy: { |
| 92 | + protocol: 'FixedRatio' |
| 93 | + rules: [ |
| 94 | + { |
| 95 | + deploymentId: '' |
| 96 | + description: 'Default rule routing all traffic' |
| 97 | + ruleId: 'default' |
| 98 | + trafficPercentage: 100 |
| 99 | + } |
| 100 | + ] |
| 101 | + } |
| 102 | + } |
| 103 | + |
| 104 | + @description('Create agent application deployment in Foundry Agent Service.') |
| 105 | + resource deploymentApp 'agentDeployments' = { |
| 106 | + name: 'agentdeploychat' |
| 107 | + properties: { |
| 108 | + agents: [ |
| 109 | + { |
| 110 | + agentName: 'baseline-chatbot-agent' |
| 111 | + agentVersion: agentVersion |
| 112 | + } |
| 113 | + ] |
| 114 | + displayName: 'Example of an agent deployment that runs an Agent Application referencing a specific agent version.' |
| 115 | + deploymentType: 'Managed' // prompt-based agent deployment |
| 116 | + protocols: [ |
| 117 | + { |
| 118 | + protocol: 'Responses' |
| 119 | + version: '1.0' |
| 120 | + } |
| 121 | + ] |
| 122 | + } |
| 123 | + dependsOn: [ |
| 124 | + agentBlobDataContributorAssignment |
| 125 | + agentBlobDataOwnerConditionalAssignment |
| 126 | + |
| 127 | + agentAISearchContributorAssignment |
| 128 | + agentAISearchIndexDataContributorAssignment |
| 129 | + |
| 130 | + agentDbCosmosDbOperatorAssignment |
| 131 | + agentContainersWriterSqlAssignment |
| 132 | + ] |
| 133 | + } |
| 134 | + } |
| 135 | + } |
| 136 | +} |
| 137 | + |
| 138 | +// Role assignments |
| 139 | + |
| 140 | +@description('Grant the Foundry application agent identity Storage Account Blob Data Contributor user role permissions.') |
| 141 | +module agentBlobDataContributorAssignment './modules/storageAccountRoleAssignment.bicep' = { |
| 142 | + name: 'agentBlobDataContributorAssignmentDeploy' |
| 143 | + params: { |
| 144 | + roleDefinitionId: storageBlobDataContributorRole.id |
| 145 | + principalId: foundry::project::application.properties.defaultInstanceIdentity.clientId |
| 146 | + existingStorageAccountName: agentStorageAccount.name |
| 147 | + } |
| 148 | +} |
| 149 | + |
| 150 | +@description('Grant the Foundry application agent identity the Storage Account Blob Data Owner user role permissions.') |
| 151 | +module agentBlobDataOwnerConditionalAssignment './modules/storageAccountRoleAssignment.bicep' = { |
| 152 | + name: 'agentBlobDataOwnerConditionalAssignmentDeploy' |
| 153 | + params: { |
| 154 | + roleDefinitionId: storageBlobDataOwnerRole.id |
| 155 | + principalId: foundry::project::application.properties.defaultInstanceIdentity.clientId |
| 156 | + existingStorageAccountName: agentStorageAccount.name |
| 157 | + conditionVersion: '2.0' |
| 158 | + condition: '((!(ActionMatches{\'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags/read\'}) AND !(ActionMatches{\'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/filter/action\'}) AND !(ActionMatches{\'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags/write\'}) ) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/containers:name] StringStartsWithIgnoreCase \'${workspaceIdAsGuid}\'))' |
| 159 | + } |
| 160 | +} |
| 161 | + |
| 162 | +@description('Grant the Foundry application agent identity AI Search Contributor user role permissions.') |
| 163 | +module agentAISearchContributorAssignment './modules/aiSearchRoleAssignment.bicep' = { |
| 164 | + name: 'agentAISearchContributorAssignmentDeploy' |
| 165 | + params: { |
| 166 | + roleDefinitionId: azureAISearchServiceContributorRole.id |
| 167 | + principalId: foundry::project::application.properties.defaultInstanceIdentity.clientId |
| 168 | + existingAISearchAccountName: azureAiSearchService.name |
| 169 | + } |
| 170 | +} |
| 171 | + |
| 172 | +@description('Grant the Foundry application agent identity AI Search Data Contributor user role permissions.') |
| 173 | +module agentAISearchIndexDataContributorAssignment './modules/aiSearchRoleAssignment.bicep' = { |
| 174 | + name: 'agentAISearchIndexDataContributorAssignmentDeploy' |
| 175 | + params: { |
| 176 | + roleDefinitionId: azureAISearchIndexDataContributorRole.id |
| 177 | + principalId: foundry::project::application.properties.defaultInstanceIdentity.clientId |
| 178 | + existingAISearchAccountName: azureAiSearchService.name |
| 179 | + } |
| 180 | +} |
| 181 | + |
| 182 | +@description('Grant the Foundry application agent identity Cosmos DB Db Operator user role permissions.') |
| 183 | +module agentDbCosmosDbOperatorAssignment './modules/cosmosdbRoleAssignment.bicep' = { |
| 184 | + name: 'agentDbCosmosDbOperatorAssignmentDeploy' |
| 185 | + params: { |
| 186 | + roleDefinitionId: cosmosDbOperatorRole.id |
| 187 | + principalId: foundry::project::application.properties.defaultInstanceIdentity.clientId |
| 188 | + existingCosmosDbAccountName: cosmosDbAccount.name |
| 189 | + } |
| 190 | +} |
| 191 | + |
| 192 | +// Sql Role Assignments |
| 193 | + |
| 194 | +@description('Assign the Foundry application agent identity the ability to read and write data in all collections within enterprise_memory database.') |
| 195 | +module agentContainersWriterSqlAssignment './modules/cosmosdbSqlRoleAssignment.bicep' = { |
| 196 | + name: 'agentContainersWriterSqlAssignmentDeploy' |
| 197 | + params: { |
| 198 | + roleDefinitionId: cosmosDbAccount::dataContributorRole.id |
| 199 | + principalId: foundry::project::application.properties.defaultInstanceIdentity.clientId |
| 200 | + existingCosmosDbAccountName: cosmosDbAccount.name |
| 201 | + existingCosmosDbName: 'enterprise_memory' |
| 202 | + existingCosmosCollectionTypeName: 'containers' |
| 203 | + scopeUserContainerId: scopeAllContainers |
| 204 | + } |
| 205 | +} |
| 206 | + |
| 207 | +// ---- Outputs ---- |
| 208 | +output agentApplicationBaseUrl string = foundry::project::application.properties.baseUrl |
0 commit comments