-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.bicep
310 lines (269 loc) · 11 KB
/
main.bicep
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
targetScope = 'subscription'
@minLength(1)
@maxLength(64)
@description('Name of the the environment which is used to generate a short unique hash used in all resources.')
param environmentName string
@minLength(1)
@description('Primary location for all resources')
param location string
var _abbrs = loadJsonContent('./abbreviations.json')
param deploymentTimestamp string = utcNow()
// Names parameters
param aiHubName string = ''
param aiProjectName string = ''
param resourceGroupName string = ''
param aiResourceGroupName string = ''
param appInsightsName string = ''
param appServiceName string = ''
var _appServiceName = !empty(appServiceName) ? appServiceName : '${_abbrs.webSitesAppService}${_resourceToken}'
param appServicePlanName string = ''
var _appServicePlanName = !empty(appServicePlanName) ? appServicePlanName : '${_abbrs.webSitesAppService}${_resourceToken}'
param containerRegistryName string = ''
param containerRepositoryName string = ''
var _containerRepositoryName = !empty(containerRepositoryName) ? containerRepositoryName : 'rag-project'
param keyVaultName string = ''
param logAnalyticsName string = ''
param openAiName string = ''
param searchServiceName string = ''
param storageAccountName string = ''
// Azure OpenAI parameters
param oaiApiVersion string = '2023-05-15'
param oaiChatDeployment string = 'gpt-35-turbo'
param oaiEmbeddingDeployment string = 'text-embedding-ada-002'
param oaiEmbeddingModel string = 'text-embedding-ada-002'
// Use sample data for Azure Search Index?
param azureSearchIndexSampleData string = ''
var _azureSearchIndexSampleData = !empty(azureSearchIndexSampleData) ? azureSearchIndexSampleData : 'true'
@description('User or service principal identity to assign application roles')
param principalId string = ''
param principalType string = 'ServicePrincipal'
// Flow parameters
param promptFlowWorkerNum string = ''
var _promptFlowWorkerNum = !empty(promptFlowWorkerNum) ? promptFlowWorkerNum : '1'
param promptFlowServingEngine string = ''
var _promptFlowServingEngine = !empty(promptFlowServingEngine) ? promptFlowServingEngine : 'fastapi'
var _resourceToken = toLower(uniqueString(subscription().id, environmentName, location, deploymentTimestamp))
var _keyVaultName = !empty(keyVaultName) ? keyVaultName : '${_abbrs.keyVaultVaults}${_resourceToken}'
// tags that should be applied to all resources.
var _tags = {
// Tag all resources with the environment name.
'azd-env-name': environmentName
}
// Organize resources in a resource group
resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
name: !empty(resourceGroupName) ? resourceGroupName : '${_abbrs.resourcesResourceGroups}${environmentName}'
location: location
tags: _tags
}
var _openAiConfig = loadYamlContent('./ai.yaml')
var _openAiModelDeployments = array(contains(_openAiConfig, 'deployments') ? _openAiConfig.deployments : [])
module ai 'core/host/ai-environment.bicep' = {
name: 'ai'
scope: resourceGroup(!empty(aiResourceGroupName) ? aiResourceGroupName : rg.name)
params: {
location: location
tags: _tags
hubName: !empty(aiHubName) ? aiHubName : 'ai-hub-${_resourceToken}'
projectName: !empty(aiProjectName) ? aiProjectName : 'ai-project-${_resourceToken}'
logAnalyticsName: !empty(logAnalyticsName) ? logAnalyticsName : '${_abbrs.operationalInsightsWorkspaces}${_resourceToken}'
appInsightsName: !empty(appInsightsName) ? appInsightsName : '${_abbrs.insightsComponents}${_resourceToken}'
containerRegistryName: !empty(containerRegistryName) ? containerRegistryName : '${_abbrs.containerRegistryRegistries}${_resourceToken}'
keyVaultName: _keyVaultName
storageAccountName: !empty(storageAccountName)? storageAccountName : '${_abbrs.storageStorageAccounts}${_resourceToken}'
openAiName: !empty(openAiName) ? openAiName : 'aoai-${_resourceToken}'
openAiModelDeployments: _openAiModelDeployments
searchName: !empty(searchServiceName) ? searchServiceName : 'srch-${_resourceToken}'
}
}
module appServicePlan './core/host/appserviceplan.bicep' = {
name: 'appServicePlan'
scope: rg
params: {
name: _appServicePlanName
location: location
tags: _tags
sku: {
name: 'P0v3'
capacity: 1
}
kind: 'linux'
}
}
module appService 'core/host/appservice.bicep' = {
name: 'appService'
scope: rg
params: {
name: _appServiceName
applicationInsightsName: ai.outputs.appInsightsName
runtimeName: 'DOCKER'
runtimeVersion: '${_containerRepositoryName}:dummy'
keyVaultName: _keyVaultName
location: location
tags: union(_tags, { 'azd-service-name': 'rag-flow' })
appServicePlanId: appServicePlan.outputs.id
scmDoBuildDuringDeployment: false
appSettings: {
WEBSITES_ENABLE_APP_SERVICE_STORAGE: false
DOCKER_REGISTRY_SERVER_URL: 'https://${ai.outputs.containerRegistryName}.azurecr.io'
WEBSITES_PORT: '80'
AZURE_SUBSCRIPTION_ID: subscription().subscriptionId
AZURE_RESOURCE_GROUP: rg.name
AZUREAI_PROJECT_NAME: ai.outputs.projectName
PROMPTFLOW_WORKER_NUM: _promptFlowWorkerNum
PROMPTFLOW_SERVING_ENGINE: _promptFlowServingEngine
AZURE_OPENAI_ENDPOINT: ai.outputs.openAiEndpoint
AZURE_OPENAI_CHAT_DEPLOYMENT: oaiChatDeployment
AZURE_OPENAI_EMBEDDING_DEPLOYMENT: oaiEmbeddingDeployment
AZURE_OPENAI_EMBEDDING_MODEL: oaiEmbeddingModel
AZURE_OPENAI_API_VERSION: oaiApiVersion
AZURE_SEARCH_ENDPOINT: ai.outputs.searchEndpoint
acrUseManagedIdentityCreds: true
}
}
}
module storageBlobDataReaderRoleToProject 'core/security/role.bicep' = {
scope: rg
name: 'storage-blob-data-reader-role'
params: {
principalId: ai.outputs.projectPrincipalId
roleDefinitionId: '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' // Storage Blob Data Reader role
principalType: 'ServicePrincipal' // Replace with the correct principal type if needed
}
}
module storageBlobDataReaderRoleToUser 'core/security/role.bicep' = {
scope: rg
name: 'user-storage-blob-data-reader-role'
params: {
principalId: principalId
roleDefinitionId: '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' // Storage Blob Data Reader role
principalType: principalType // Replace with the correct principal type if needed
}
}
module userAcrRolePush 'core/security/role.bicep' = {
name: 'user-acr-role-push'
scope: rg
params: {
principalId: principalId
roleDefinitionId: '8311e382-0749-4cb8-b61a-304f252e45ec'
principalType: principalType
}
}
module userAcrRolePull 'core/security/role.bicep' = {
name: 'user-acr-role-pull'
scope: rg
params: {
principalId: principalId
roleDefinitionId: '7f951dda-4ed3-4680-a7ca-43fe172d538d'
principalType: principalType
}
}
module openaiRoleUser 'core/security/role.bicep' = if (!empty(principalId)) {
scope: rg
name: 'openai-role-user'
params: {
principalId: principalId
roleDefinitionId: '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' //Cognitive Services OpenAI User
principalType: principalType
}
}
module userRoleDataScientist 'core/security/role.bicep' = {
name: 'user-role-data-scientist'
scope: rg
params: {
principalId: principalId
roleDefinitionId: 'f6c7c914-8db3-469d-8ca1-694a8f32e121'
principalType: principalType
}
}
module userRoleSecretsReader 'core/security/role.bicep' = {
name: 'user-role-secrets-reader'
scope: rg
params: {
principalId: principalId
roleDefinitionId: 'ea01e6af-a1c1-4350-9563-ad00f8c72ec5'
principalType: principalType
}
}
module userAiSearchRole 'core/security/role.bicep' = if (!empty(principalId)) {
scope: rg
name: 'user-ai-search-index-data-contributor'
params: {
principalId: principalId
roleDefinitionId: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' //Search Index Data Contributor
principalType: principalType
}
}
module userAiSearchServiceContributor 'core/security/role.bicep' = if (!empty(principalId)) {
scope: rg
name: 'user-ai-search-service-contributor'
params: {
principalId: principalId
roleDefinitionId: '7ca78c08-252a-4471-8644-bb5ff32d4ba0' //Search Service Contributor
principalType: principalType
}
}
module openaiRoleBackend 'core/security/role.bicep' = {
scope: rg
name: 'openai-role-backend'
params: {
principalId: appService.outputs.identityPrincipalId
roleDefinitionId: '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' //Cognitive Services OpenAI User
principalType: 'ServicePrincipal'
}
}
module aiSearchServiceContributor 'core/security/role.bicep' = {
scope: rg
name: 'ai-search-service-contributor'
params: {
principalId: appService.outputs.identityPrincipalId
roleDefinitionId: '7ca78c08-252a-4471-8644-bb5ff32d4ba0' //Search Service Contributor
principalType: 'ServicePrincipal'
}
}
module aiSearchRole 'core/security/role.bicep' = {
scope: rg
name: 'ai-search-index-data-contributor'
params: {
principalId: appService.outputs.identityPrincipalId
roleDefinitionId: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' //Search Index Data Contributor
principalType: 'ServicePrincipal'
}
}
module appserviceAcrRolePull 'core/security/role.bicep' = {
scope: rg
name: 'app-service-acr-role-pull'
params: {
principalId: appService.outputs.identityPrincipalId
roleDefinitionId: '7f951dda-4ed3-4680-a7ca-43fe172d538d'
principalType: 'ServicePrincipal'
}
}
// output for post processing
output AZURE_TENANT_ID string = tenant().tenantId
output AZURE_SUBSCRIPTION_ID string = subscription().subscriptionId
output AZURE_RESOURCE_GROUP string = rg.name
output AZURE_PRINCIPAL_ID string = principalId
output AZURE_PRINCIPAL_TYPE string = principalType
output AZURE_OPENAI_ENDPOINT string = ai.outputs.openAiEndpoint
output AZURE_OPENAI_API_VERSION string = oaiApiVersion
output AZURE_OPENAI_CHAT_DEPLOYMENT string = oaiChatDeployment
output AZURE_OPENAI_EMBEDDING_DEPLOYMENT string = oaiEmbeddingDeployment
output AZURE_OPENAI_EMBEDDING_MODEL string = oaiEmbeddingModel
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = ai.outputs.containerRegistryEndpoint
output AZURE_KEY_VAULT_ENDPOINT string = ai.outputs.keyVaultEndpoint
output AZURE_SEARCH_ENDPOINT string = ai.outputs.searchEndpoint
output AZUREAI_HUB_NAME string = ai.outputs.hubName
output AZUREAI_PROJECT_NAME string = ai.outputs.projectName
output AZURE_APP_INSIGHTS_NAME string = ai.outputs.appInsightsName
output AZURE_APP_SERVICE_NAME string = _appServiceName
output AZURE_APP_SERVICE_PLAN_NAME string = _appServicePlanName
output AZURE_CONTAINER_REGISTRY_NAME string = ai.outputs.containerRegistryName
output AZURE_CONTAINER_REPOSITORY_NAME string = _containerRepositoryName
output AZURE_KEY_VAULT_NAME string = ai.outputs.keyVaultName
output AZURE_LOG_ANALYTICS_NAME string = ai.outputs.logAnalyticsWorkspaceName
output AZURE_OPENAI_NAME string = ai.outputs.openAiName
output AZURE_SEARCH_NAME string = ai.outputs.searchName
output AZURE_STORAGE_ACCOUNT_NAME string = ai.outputs.storageAccountName
output PROMPTFLOW_WORKER_NUM string = _promptFlowWorkerNum
output PROMPTFLOW_SERVING_ENGINE string = _promptFlowServingEngine
output LOAD_AZURE_SEARCH_SAMPLE_DATA string = _azureSearchIndexSampleData