-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathprivate-apim.bicep
218 lines (186 loc) · 7.6 KB
/
private-apim.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
@description('The location into which regionally scoped resources should be deployed. Note that Front Door is a global resource.')
param location string = resourceGroup().location
@description('The IP address prefix (CIDR range) to use when deploying the virtual network.')
param vnetIPPrefix string = '10.0.0.0/16'
@description('The SKU of the API Management instance.')
@allowed([
'Premium'
'Developer'
'BasicV2'
'StandardV2'
])
param apiManagementSku string = 'Developer'
@description('The IP address prefix (CIDR range) to use when deploying the API Management subnet within the virtual network.')
param apiManagementSubnetIPPrefix string = '10.0.0.0/24'
@description('The name of the API publisher. This information is used by API Management.')
param apiManagementPublisherName string = 'Contoso'
@description('The email address of the API publisher. This information is used by API Management.')
param apiManagementPublisherEmail string = 'admin@contoso.com'
@description('Provide the Name of the Azure OpenAI service.')
param apiServiceNamePrimary string = 'Insert_Your_Azure_OpenAi_Name_Here'
@description('Provide the Resource Group Name of the Azure OpenAI service.')
param apiServiceRgPrimary string = 'Insert_Resource_Group_Name_Here'
@description('If you want to provide resiliency when single region exceeds quota, then select Multi and provide URL to an additional Azure OpenAI endpoint. Otherwise, maintain default entry of Single and only provide one Azure OpenAI endpoint.')
@allowed([
'Single'
'Multi'
])
param azureOpenAiRegionType string = 'Single'
@description('If you select Multi in azureOpenAiRegionType, then you must provide another Azure OpenAI Name here.')
param apiServiceNameSecondary string = 'Maybe-Insert_Your_Secondary_Azure_OpenAi_Name_Here'
@description('If you select Multi in azureOpenAiRegionType, provide the Resource Group Name of the Azure OpenAI service.')
param apiServiceRgSecondary string = 'Maybe-Insert_Resource_Group_Name_Here'
@description('If you want to enable retry policy for the API, set this to true. Otherwise, set this to false.')
param enableRetryPolicy bool = false
var apiServiceUrlPrimary = 'https://${apiServiceNamePrimary}.openai.azure.com/openai'
var apiServiceUrlSecondary = 'https://${apiServiceNameSecondary}.openai.azure.com/openai'
// The following logic is used to determine the OpenAPI XML policy file to use based on the region type and retry policy setting.
var openApiXmlRetry = enableRetryPolicy ? 'https://raw.githubusercontent.com/microsoft/AzureOpenAI-with-APIM/main/apim_policies/AOAI_Policy-Managed_Identity_with_Retry_SingleRegion.xml' : 'https://raw.githubusercontent.com/microsoft/AzureOpenAI-with-APIM/main/apim_policies/AOAI_Policy-Managed_Identity.xml'
var openApiXml = azureOpenAiRegionType == 'Multi' ? 'https://raw.githubusercontent.com/microsoft/AzureOpenAI-with-APIM/main/apim_policies/AOAI_Policy-Managed_Identity_with_Retry_MultiRegion.xml' : openApiXmlRetry
var openApiJson = 'https://raw.githubusercontent.com/microsoft/AzureOpenAI-with-APIM/main/api_definitions/AzureOpenAI_OpenAPI.json'
var apiNetwork = 'Internal'
var apiManagementSkuCount = 1
var apiName = 'azure-openai-service-api'
var apiPath = ''
var apiSubscriptionName = 'AzureOpenAI-Consumer-Chat'
var unique = uniqueString(resourceGroup().id, subscription().id)
var vnetName = 'vNet-${unique}'
var apiManagementServiceName = 'apim-${unique}'
var logAnalyticsName = 'law-${unique}'
var eventHubName = 'eh-${unique}'
var eventHubNamespaceName = 'ehn-${unique}'
var applicationInsightsName = 'appIn-${unique}'
var privateDnsZoneName = 'azure-api.net'
var azureRoles = loadJsonContent('azure_roles.json')
module logAnalyticsWorkspace 'modules/log-analytics-workspace.bicep' = {
name: 'log-analytics-workspace'
params: {
location: location
logAnalyticsName: logAnalyticsName
}
}
module eventHub 'modules/event-hub.bicep' = {
name: 'event-hub'
params: {
location: location
eventHubNamespaceName: eventHubNamespaceName
eventHubName: eventHubName
}
}
module applicationInsights 'modules/app-insights.bicep' = {
name: 'application-insights'
params: {
location: location
workspaceName: logAnalyticsName
applicationInsightsName: applicationInsightsName
}
dependsOn: [
logAnalyticsWorkspace
]
}
module network 'modules/network.bicep' = {
name: 'network'
params: {
vnetName: vnetName
location: location
vnetIPPrefix: vnetIPPrefix
apiManagementSubnetIPPrefix: apiManagementSubnetIPPrefix
}
dependsOn: [
logAnalyticsWorkspace
]
}
module apiManagement 'modules/api-management-private.bicep' = {
name: 'api-management'
params: {
location: location
serviceName: apiManagementServiceName
publisherName: apiManagementPublisherName
publisherEmail: apiManagementPublisherEmail
skuName: apiManagementSku
skuCount: apiManagementSkuCount
subnetResourceId: network.outputs.apiManagementSubnetResourceId
virtualNetworkType: apiNetwork
aiName: applicationInsightsName
eventHubName: eventHubName
eventHubNamespaceName: eventHubNamespaceName
}
dependsOn: [
network
applicationInsights
eventHub
logAnalyticsWorkspace
]
}
module api 'modules/api.bicep' = {
name: 'api'
params: {
apimName: apiManagementServiceName
apiName: apiName
apiPath: apiPath
openApiJson : openApiJson
openApiXml : openApiXml
serviceUrlPrimary : apiServiceUrlPrimary
serviceUrlSecondary: apiServiceUrlSecondary
azureOpenAiRegionType: azureOpenAiRegionType
apiSubscriptionName: apiSubscriptionName
aiLoggerId: apiManagement.outputs.aiLoggerId
}
dependsOn: [
apiManagement
]
}
module privateDnsZone 'modules/private-dns-zone-apim.bicep' = {
name: 'private-dns-zone'
params: {
privateDnsZoneName: privateDnsZoneName
apimName: apiManagementServiceName
vnetName: vnetName
}
dependsOn: [
apiManagement
]
}
resource eventHubNamespaceParent 'Microsoft.EventHub/namespaces@2021-01-01-preview' existing = {
name: eventHubNamespaceName
}
resource azureEventHubsDataSender 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(subscription().id, resourceGroup().id, eventHubNamespaceName)
scope: eventHubNamespaceParent
properties: {
principalId: apiManagement.outputs.apiManagementIdentityPrincipalId
principalType: 'ServicePrincipal'
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', azureRoles.AzureEventHubsDataSender)
}
dependsOn: [
apiManagement
]
}
module openAiUserPrimary 'modules/role.bicep' = {
name: 'openAiUserPrimary'
scope: resourceGroup(apiServiceRgPrimary)
params: {
roleName: guid(subscription().id, resourceGroup().id, eventHubNamespaceName, 'Primary')
principalId: apiManagement.outputs.apiManagementIdentityPrincipalId
principalType: 'ServicePrincipal'
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', azureRoles.CognitiveServicesOpenAIUser)
}
dependsOn: [
apiManagement
]
}
module openAiUserSecondary 'modules/role.bicep' = {
name: 'openAiUserSecondary'
scope: resourceGroup(apiServiceRgSecondary)
params: {
roleName: guid(subscription().id, resourceGroup().id, eventHubNamespaceName, 'Primary')
principalId: apiManagement.outputs.apiManagementIdentityPrincipalId
principalType: 'ServicePrincipal'
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', azureRoles.CognitiveServicesOpenAIUser)
}
dependsOn: [
apiManagement
]
}
output apiManagementProxyHostName string = apiManagement.outputs.apiManagementProxyHostName
output apiManagementPortalHostName string = apiManagement.outputs.apiManagementDeveloperPortalHostName