-
Notifications
You must be signed in to change notification settings - Fork 189
Expand file tree
/
Copy pathmain.bicep
More file actions
258 lines (224 loc) · 9.6 KB
/
main.bicep
File metadata and controls
258 lines (224 loc) · 9.6 KB
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
// ========== main.bicep ========== //
targetScope = 'resourceGroup'
@minLength(3)
@maxLength(20)
@description('A unique prefix for all resources in this deployment. This should be 3-20 characters long:')
param environmentName string
var uniqueId = toLower(uniqueString(subscription().id, environmentName, resourceGroup().location))
var solutionPrefix = 'cps-${padLeft(take(uniqueId, 12), 12, '0')}'
@description('Location used for Azure Cosmos DB, Azure Container App deployment')
param secondaryLocation string = 'EastUs2'
@minLength(1)
@description('Location for the Azure AI Content Understanding service deployment:')
@allowed(['WestUS', 'SwedenCentral', 'AustraliaEast'])
@metadata({
azd: {
type: 'location'
}
})
param contentUnderstandingLocation string
@minLength(1)
@description('GPT model deployment type:')
@allowed([
'Standard'
'GlobalStandard'
])
param deploymentType string = 'GlobalStandard'
@description('Name of the GPT model to deploy:')
param gptModelName string = 'gpt-4o'
@description('Version of the GPT model to deploy:')
param gptModelVersion string = '2024-08-06'
//var gptModelVersion = '2024-02-15-preview'
@minValue(10)
@description('Capacity of the GPT deployment:')
// You can increase this, but capacity is limited per model/region, so you will get errors if you go over
// https://learn.microsoft.com/en-us/azure/ai-services/openai/quotas-limits
param gptDeploymentCapacity int = 100
@description('Minimum number of replicas to be added for Container App')
param minReplicaContainerApp int = 1
@description('Maximum number of replicas to be added for Container App')
param maxReplicaContainerApp int = 1
@description('Minimum number of replicas to be added for Container Api')
param minReplicaContainerApi int = 1
@description('Maximum number of replicas to be added for Container Api')
param maxReplicaContainerApi int = 1
@description('Minimum number of replicas to be added for Container Web App')
param minReplicaContainerWeb int = 1
@description('Maximum number of replicas to be added for Container Web App')
param maxReplicaContainerWeb int = 1
@description('Set this flag to true only if you are deplpoying from Local')
param useLocalBuild string = 'false'
@description('Optional: Existing Log Analytics Workspace Resource ID')
param existingLogAnalyticsWorkspaceId string = ''
param imageTag string = 'latest'
var containerImageEndPoint = 'cpscontainerreg.azurecr.io'
var resourceGroupLocation = resourceGroup().location
// Load the abbrevations file required to name the azure resources.
var abbrs = loadJsonContent('./abbreviations.json')
// Convert input to lowercase
var useLocalBuildLower = toLower(useLocalBuild)
// ========== Managed Identity ========== //
module managedIdentityModule 'deploy_managed_identity.bicep' = {
name: 'deploy_managed_identity'
params: {
solutionName: solutionPrefix
miName: '${abbrs.security.managedIdentity}${solutionPrefix}'
solutionLocation: resourceGroupLocation
}
scope: resourceGroup(resourceGroup().name)
}
// ========== Key Vault Module ========== //
module kvault 'deploy_keyvault.bicep' = {
name: 'deploy_keyvault'
params: {
solutionLocation: resourceGroupLocation
keyvaultName: '${abbrs.security.keyVault}${solutionPrefix}'
managedIdentityObjectId: managedIdentityModule.outputs.managedIdentityOutput.objectId
}
scope: resourceGroup(resourceGroup().name)
}
// ========== Application insights ========== //
module applicationInsights 'deploy_app_insights.bicep' = {
name: 'deploy_app_insights'
params: {
existingLogAnalyticsWorkspaceId: existingLogAnalyticsWorkspaceId
applicationInsightsName: '${abbrs.managementGovernance.applicationInsights}${solutionPrefix}'
logAnalyticsWorkspaceName: '${abbrs.managementGovernance.logAnalyticsWorkspace}${solutionPrefix}'
}
}
// ========== Container Registry ========== //
module containerRegistry 'deploy_container_registry.bicep' = {
name: 'deploy_container_registry'
params: {
environmentName: environmentName
}
}
// ========== Storage Account ========== //
module storage 'deploy_storage_account.bicep' = {
name: 'deploy_storage_account'
params: {
solutionLocation: resourceGroupLocation
managedIdentityObjectId: managedIdentityModule.outputs.managedIdentityOutput.objectId
saName: '${abbrs.storage.storageAccount}${solutionPrefix}'
}
}
// ========== AI Foundry and related resources ========== //
module aifoundry 'deploy_ai_foundry.bicep' = {
name: 'deploy_ai_foundry'
params: {
solutionName: solutionPrefix
solutionLocation: resourceGroupLocation
keyVaultName: kvault.outputs.keyvaultName
cuLocation: contentUnderstandingLocation
deploymentType: deploymentType
gptModelName: gptModelName
gptModelVersion: gptModelVersion
gptDeploymentCapacity: gptDeploymentCapacity
managedIdentityObjectId: managedIdentityModule.outputs.managedIdentityOutput.objectId
containerRegistryId: containerRegistry.outputs.createdAcrId
applicationInsightsId: applicationInsights.outputs.id
}
scope: resourceGroup(resourceGroup().name)
}
module containerAppEnv './container_app/deploy_container_app_env.bicep' = {
name: 'deploy_container_app_env'
params: {
solutionName: solutionPrefix
containerEnvName: '${abbrs.containers.containerAppsEnvironment}${solutionPrefix}'
location: secondaryLocation
logAnalyticsWorkspaceName: applicationInsights.outputs.logAnalyticsWorkspaceName
logAnalyticsWorkspaceResourceGroup: applicationInsights.outputs.logAnalyticsWorkspaceResourceGroup
logAnalyticsWorkspaceSubscription: applicationInsights.outputs.logAnalyticsWorkspaceSubscription
}
}
module containerApps './container_app/deploy_container_app_api_web.bicep' = {
name: 'deploy_container_app_api_web'
params: {
solutionName: solutionPrefix
location: secondaryLocation
appConfigEndPoint: ''
containerAppApiEndpoint: ''
containerAppWebEndpoint: ''
azureContainerRegistry: containerImageEndPoint
containerAppEnvId: containerAppEnv.outputs.containerEnvId
containerRegistryReaderId: containerAppEnv.outputs.containerRegistryReaderId
minReplicaContainerApp: minReplicaContainerApp
maxReplicaContainerApp: maxReplicaContainerApp
minReplicaContainerApi: minReplicaContainerApi
maxReplicaContainerApi: maxReplicaContainerApi
minReplicaContainerWeb: minReplicaContainerWeb
maxReplicaContainerWeb: maxReplicaContainerWeb
useLocalBuild: 'false'
imageTag: 'latest'
}
}
// ========== Cosmos Database for Mongo DB ========== //
module cosmosdb './deploy_cosmos_db.bicep' = {
name: 'deploy_cosmos_db'
params: {
cosmosAccountName: '${abbrs.databases.cosmosDBDatabase}${solutionPrefix}'
solutionLocation: secondaryLocation
kind: 'MongoDB'
}
}
// ========== App Configuration ========== //
module appconfig 'deploy_app_config_service.bicep' = {
name: 'deploy_app_config_service'
scope: resourceGroup(resourceGroup().name)
params: {
appConfigName: '${abbrs.developerTools.appConfigurationStore}${solutionPrefix}'
storageBlobUrl: storage.outputs.storageBlobUrl
storageQueueUrl: storage.outputs.storageQueueUrl
openAIEndpoint: aifoundry.outputs.aiServicesTarget
contentUnderstandingEndpoint: aifoundry.outputs.aiServicesCUEndpoint
gptModelName: gptModelName
keyVaultId: kvault.outputs.keyvaultId
aiProjectConnectionString: aifoundry.outputs.aiProjectConnectionString
cosmosDbName: cosmosdb.outputs.cosmosAccountName
}
}
// ========== Role Assignments ========== //
module roleAssignments 'deploy_role_assignments.bicep' = {
name: 'deploy_role_assignments'
params: {
appConfigResourceId: appconfig.outputs.appConfigId
conainerAppPrincipalIds: [
containerApps.outputs.containerAppPrincipalId
containerApps.outputs.containerAppApiPrincipalId
containerApps.outputs.containerAppWebPrincipalId
]
storageResourceId: storage.outputs.storageId
storagePrincipalId: storage.outputs.storagePrincipalId
containerApiPrincipalId: containerApps.outputs.containerAppApiPrincipalId
containerAppPrincipalId: containerApps.outputs.containerAppPrincipalId
aiServiceCUId: aifoundry.outputs.aiServicesCuId
aiServiceId: aifoundry.outputs.aiServicesId
containerRegistryReaderPrincipalId: containerAppEnv.outputs.containerRegistryReaderPrincipalId
}
}
module updateContainerApp './container_app/deploy_container_app_api_web.bicep' = {
name: 'deploy_update_container_app_update'
params: {
solutionName: solutionPrefix
location: secondaryLocation
azureContainerRegistry: useLocalBuildLower == 'true' ? containerRegistry.outputs.acrEndpoint : containerImageEndPoint
appConfigEndPoint: appconfig.outputs.appConfigEndpoint
containerAppEnvId: containerAppEnv.outputs.containerEnvId
containerRegistryReaderId: containerAppEnv.outputs.containerRegistryReaderId
containerAppWebEndpoint: containerApps.outputs.containweAppWebEndPoint
containerAppApiEndpoint: containerApps.outputs.containweAppApiEndPoint
minReplicaContainerApp: minReplicaContainerApp
maxReplicaContainerApp: maxReplicaContainerApp
minReplicaContainerApi: minReplicaContainerApi
maxReplicaContainerApi: maxReplicaContainerApi
minReplicaContainerWeb: minReplicaContainerWeb
maxReplicaContainerWeb: maxReplicaContainerWeb
useLocalBuild: useLocalBuildLower
imageTag: imageTag
}
dependsOn: [roleAssignments]
}
output CONTAINER_WEB_APP_NAME string = containerApps.outputs.containerAppWebName
output CONTAINER_API_APP_NAME string = containerApps.outputs.containerAppApiName
output CONTAINER_WEB_APP_FQDN string = containerApps.outputs.containweAppWebEndPoint
output CONTAINER_API_APP_FQDN string = containerApps.outputs.containweAppApiEndPoint