Skip to content

Commit

Permalink
Merge pull request #99 from Azure-Samples/feature/add-progressive-pol…
Browse files Browse the repository at this point in the history
…icies-1-lab

Feature/add zero-to-production lab
  • Loading branch information
vieiraae authored Feb 4, 2025
2 parents 4932d72 + 2984105 commit dd9b906
Show file tree
Hide file tree
Showing 11 changed files with 1,372 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ __pycache__/
.azure/

labs-in-progress/
params.json
params*.json
policy-updated.xml

.vscode/**/*
Expand Down
26 changes: 26 additions & 0 deletions labs/zero-to-production/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# APIM ❤️ OpenAI

## [Zero-to-Production lab](zero-to-production.ipynb)

Playground to create a combination of several policies in an iterative approach. We start with load balancing, then progressively add token emitting, rate limiting, and, eventually, semantic caching. Each of these sets of policies is derived from other labs in this repo.

[View policy configuration](policy.xml)

### Prerequisites

- [Python 3.12 or later version](https://www.python.org/) installed
- [Pandas Library](https://pandas.pydata.org) installed
- [VS Code](https://code.visualstudio.com/) installed with the [Jupyter notebook extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) enabled
- [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed
- [An Azure Subscription](https://azure.microsoft.com/free/) with Contributor permissions
- [Access granted to Azure OpenAI](https://aka.ms/oai/access)
- [Sign in to Azure with Azure CLI](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively)

### 🚀 Get started

Proceed by opening the [Jupyter notebook](zero-to-production.ipynb), and follow the steps provided.

### 🗑️ Clean up resources

When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
48 changes: 48 additions & 0 deletions labs/zero-to-production/clean-up-resources.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 🗑️ Clean up resources\n",
"\n",
"When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os, sys\n",
"sys.path.insert(1, '../../shared') # add the shared directory to the Python path\n",
"import utils\n",
"\n",
"deployment_name = os.path.basename(os.path.dirname(globals()['__vsc_ipynb_file__']))\n",
"utils.cleanup_resources(deployment_name)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
134 changes: 134 additions & 0 deletions labs/zero-to-production/main.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// ------------------
// PARAMETERS
// ------------------

// Typically, parameters would be decorated with appropriate metadata and attributes, but as they are very repetetive in these labs we omit them for brevity.

param apimSku string
param openAIConfig array = []
param openAIModelName string
param openAIModelVersion string
param openAIDeploymentName string
param openAIModelCapacity int
param openAIAPIVersion string = '2024-02-01'
param policyXml string

// ------------------
// VARIABLES
// ------------------

var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
var apiManagementName = 'apim-${resourceSuffix}'
var openAISubscriptionName = 'openai-subscription'
var openAISubscriptionDescription = 'OpenAI Subscription'
var openAIAPIName = 'openai'

// ------------------
// RESOURCES
// ------------------

// 1. Log Analytics Workspace
module lawModule '../../modules/operational-insights/v1/workspaces.bicep' = {
name: 'lawModule'
}

var lawId = lawModule.outputs.id

// 2. Application Insights
module appInsightsModule '../../modules/monitor/v1/appinsights.bicep' = {
name: 'appInsightsModule'
params: {
workbookJson: loadTextContent('openai-usage-analysis-workbook.json')
lawId: lawId
customMetricsOptedInType: 'WithDimensions'
}
}

var appInsightsId = appInsightsModule.outputs.id
var appInsightsInstrumentationKey = appInsightsModule.outputs.instrumentationKey

// 3. API Management
module apimModule '../../modules/apim/v1/apim.bicep' = {
name: 'apimModule'
params: {
apimSku: apimSku
appInsightsInstrumentationKey: appInsightsInstrumentationKey
appInsightsId: appInsightsId
}
}

// 4. Cognitive Services
module openAIModule '../../modules/cognitive-services/v1/openai.bicep' = {
name: 'openAIModule'
params: {
openAIConfig: openAIConfig
openAIDeploymentName: openAIDeploymentName
openAIModelName: openAIModelName
openAIModelVersion: openAIModelVersion
openAIModelCapacity: openAIModelCapacity
apimPrincipalId: apimModule.outputs.principalId
lawId: lawId
}
}

// 5. APIM OpenAI API
module openAIAPIModule '../../modules/apim/v1/openai-api.bicep' = {
name: 'openAIAPIModule'
params: {
policyXml: policyXml
openAIConfig: openAIModule.outputs.extendedOpenAIConfig
openAIAPIVersion: openAIAPIVersion
appInsightsInstrumentationKey: appInsightsInstrumentationKey
appInsightsId: appInsightsId
}
}

// 6. Create New APIM Subscriptions

// We presume the APIM resource has been created as part of this bicep flow.
resource apim 'Microsoft.ApiManagement/service@2024-06-01-preview' existing = {
name: apiManagementName
dependsOn: [
apimModule
]
}

resource api 'Microsoft.ApiManagement/service/apis@2024-06-01-preview' existing = {
parent: apim
name: openAIAPIName
dependsOn: [
openAIAPIModule
]
}

// Ignore the subscription that gets created in the APIM module and create three new ones for this lab.
resource apimSubscriptions 'Microsoft.ApiManagement/service/subscriptions@2024-06-01-preview' = [for i in range(1, 3): {
name: '${openAISubscriptionName}${i}'
parent: apim
properties: {
allowTracing: true
displayName: '${openAISubscriptionDescription} ${i}'
scope: '/apis/${api.id}'
state: 'active'
}
dependsOn: [
api
]
}]

// ------------------
// MARK: OUTPUTS
// ------------------

output applicationInsightsAppId string = appInsightsModule.outputs.appId
output applicationInsightsName string = appInsightsModule.outputs.applicationInsightsName
output logAnalyticsWorkspaceId string = lawModule.outputs.customerId
output apimServiceId string = apimModule.outputs.id
output apimResourceGatewayURL string = apimModule.outputs.gatewayUrl

#disable-next-line outputs-should-not-contain-secrets
output apimSubscription1Key string = apimSubscriptions[0].listSecrets().primaryKey
#disable-next-line outputs-should-not-contain-secrets
output apimSubscription2Key string = apimSubscriptions[1].listSecrets().primaryKey
#disable-next-line outputs-should-not-contain-secrets
output apimSubscription3Key string = apimSubscriptions[2].listSecrets().primaryKey
Loading

0 comments on commit dd9b906

Please sign in to comment.