From f7dadda5c2928f25f9f2609f65f5d9d0af61d4a2 Mon Sep 17 00:00:00 2001 From: Wassim Chegham Date: Thu, 16 May 2024 09:19:14 +0200 Subject: [PATCH] chore: update azd/bicep setup --- azure.yaml | 15 +- infra/core/ai/cognitiveservices.bicep | 4 + infra/core/host/appservice-appsettings.bicep | 17 +++ infra/core/host/appservice.bicep | 124 ++++++++++++++++ infra/core/host/appserviceplan.bicep | 22 +++ infra/core/host/functions.bicep | 87 +++++++++++ infra/core/host/staticwebapp.bicep | 25 +++- infra/core/search/search-services.bicep | 68 --------- infra/main.bicep | 146 ++++++++++--------- infra/main.parameters.json | 21 +-- swa-cli.config.json | 8 +- 11 files changed, 377 insertions(+), 160 deletions(-) create mode 100644 infra/core/host/appservice-appsettings.bicep create mode 100644 infra/core/host/appservice.bicep create mode 100644 infra/core/host/appserviceplan.bicep create mode 100644 infra/core/host/functions.bicep delete mode 100644 infra/core/search/search-services.bicep diff --git a/azure.yaml b/azure.yaml index ce4c2fc..3b1911a 100644 --- a/azure.yaml +++ b/azure.yaml @@ -1,8 +1,8 @@ name: azure-openai-assistant-javascript@1.0.0 services: webapp: - project: ./ - dist: dist + project: ./src + dist: ../dist language: js host: staticwebapp hooks: @@ -16,4 +16,13 @@ services: shell: sh run: npm run build interactive: false - continueOnError: false \ No newline at end of file + continueOnError: false + # postdeploy: + # shell: sh + # run: azd env get-values > .env && npx swa deploy --deployment-token ${DEPLOYMENT_TOKEN} && npm install --only=dev --prefix api + # interactive: false + # continueOnError: false + api: + project: ./api + language: js + host: function diff --git a/infra/core/ai/cognitiveservices.bicep b/infra/core/ai/cognitiveservices.bicep index 83e7515..1781e2f 100644 --- a/infra/core/ai/cognitiveservices.bicep +++ b/infra/core/ai/cognitiveservices.bicep @@ -27,6 +27,9 @@ resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' = { location: location tags: tags kind: kind + identity: { + type: 'SystemAssigned' + } properties: { customSubDomainName: customSubDomainName publicNetworkAccess: publicNetworkAccess @@ -53,3 +56,4 @@ resource deployment 'Microsoft.CognitiveServices/accounts/deployments@2023-05-01 output endpoint string = account.properties.endpoint output id string = account.id output name string = account.name +output identityPrincipalId string = account.identity.principalId diff --git a/infra/core/host/appservice-appsettings.bicep b/infra/core/host/appservice-appsettings.bicep new file mode 100644 index 0000000..f4b22f8 --- /dev/null +++ b/infra/core/host/appservice-appsettings.bicep @@ -0,0 +1,17 @@ +metadata description = 'Updates app settings for an Azure App Service.' +@description('The name of the app service resource within the current resource group scope') +param name string + +@description('The app settings to be applied to the app service') +@secure() +param appSettings object + +resource appService 'Microsoft.Web/sites@2022-03-01' existing = { + name: name +} + +resource settings 'Microsoft.Web/sites/config@2022-03-01' = { + name: 'appsettings' + parent: appService + properties: appSettings +} diff --git a/infra/core/host/appservice.bicep b/infra/core/host/appservice.bicep new file mode 100644 index 0000000..8753b19 --- /dev/null +++ b/infra/core/host/appservice.bicep @@ -0,0 +1,124 @@ +metadata description = 'Creates an Azure App Service in an existing Azure App Service plan.' +param name string +param location string = resourceGroup().location +param tags object = {} + +// Reference Properties +param applicationInsightsName string = '' +param appServicePlanId string +param keyVaultName string = '' +param managedIdentity bool = !empty(keyVaultName) + +// Runtime Properties +@allowed([ + 'dotnet', 'dotnetcore', 'dotnet-isolated', 'node', 'python', 'java', 'powershell', 'custom' +]) +param runtimeName string +param runtimeNameAndVersion string = '${runtimeName}|${runtimeVersion}' +param runtimeVersion string + +// Microsoft.Web/sites Properties +param kind string = 'app,linux' + +// Microsoft.Web/sites/config +param allowedOrigins array = [] +param alwaysOn bool = true +param appCommandLine string = '' +@secure() +param appSettings object = {} +param clientAffinityEnabled bool = false +param enableOryxBuild bool = contains(kind, 'linux') +param functionAppScaleLimit int = -1 +param linuxFxVersion string = runtimeNameAndVersion +param minimumElasticInstanceCount int = -1 +param numberOfWorkers int = -1 +param scmDoBuildDuringDeployment bool = false +param use32BitWorkerProcess bool = false +param ftpsState string = 'FtpsOnly' +param healthCheckPath string = '' + +resource appService 'Microsoft.Web/sites@2022-03-01' = { + name: name + location: location + tags: tags + kind: kind + properties: { + serverFarmId: appServicePlanId + siteConfig: { + linuxFxVersion: linuxFxVersion + alwaysOn: alwaysOn + ftpsState: ftpsState + minTlsVersion: '1.2' + appCommandLine: appCommandLine + numberOfWorkers: numberOfWorkers != -1 ? numberOfWorkers : null + minimumElasticInstanceCount: minimumElasticInstanceCount != -1 ? minimumElasticInstanceCount : null + use32BitWorkerProcess: use32BitWorkerProcess + functionAppScaleLimit: functionAppScaleLimit != -1 ? functionAppScaleLimit : null + healthCheckPath: healthCheckPath + cors: { + allowedOrigins: union([ 'https://portal.azure.com', 'https://ms.portal.azure.com' ], allowedOrigins) + } + } + clientAffinityEnabled: clientAffinityEnabled + httpsOnly: true + } + + identity: { type: managedIdentity ? 'SystemAssigned' : 'None' } + + resource basicPublishingCredentialsPoliciesFtp 'basicPublishingCredentialsPolicies' = { + name: 'ftp' + properties: { + allow: false + } + } + + resource basicPublishingCredentialsPoliciesScm 'basicPublishingCredentialsPolicies' = { + name: 'scm' + properties: { + allow: false + } + } +} + +// Updates to the single Microsoft.sites/web/config resources that need to be performed sequentially +// sites/web/config 'appsettings' +module configAppSettings 'appservice-appsettings.bicep' = { + name: '${name}-appSettings' + params: { + name: appService.name + appSettings: union(appSettings, + { + SCM_DO_BUILD_DURING_DEPLOYMENT: string(scmDoBuildDuringDeployment) + ENABLE_ORYX_BUILD: string(enableOryxBuild) + }, + runtimeName == 'python' && appCommandLine == '' ? { PYTHON_ENABLE_GUNICORN_MULTIWORKERS: 'true'} : {}, + !empty(applicationInsightsName) ? { APPLICATIONINSIGHTS_CONNECTION_STRING: applicationInsights.properties.ConnectionString } : {}, + !empty(keyVaultName) ? { AZURE_KEY_VAULT_ENDPOINT: keyVault.properties.vaultUri } : {}) + } +} + +// sites/web/config 'logs' +resource configLogs 'Microsoft.Web/sites/config@2022-03-01' = { + name: 'logs' + parent: appService + properties: { + applicationLogs: { fileSystem: { level: 'Verbose' } } + detailedErrorMessages: { enabled: true } + failedRequestsTracing: { enabled: true } + httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } + } + dependsOn: [configAppSettings] +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = if (!(empty(keyVaultName))) { + name: keyVaultName +} + +resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = if (!empty(applicationInsightsName)) { + name: applicationInsightsName +} + +output identityPrincipalId string = managedIdentity ? appService.identity.principalId : '' +output name string = appService.name +output uri string = 'https://${appService.properties.defaultHostName}' +output id string = appService.id diff --git a/infra/core/host/appserviceplan.bicep b/infra/core/host/appserviceplan.bicep new file mode 100644 index 0000000..2e37e04 --- /dev/null +++ b/infra/core/host/appserviceplan.bicep @@ -0,0 +1,22 @@ +metadata description = 'Creates an Azure App Service plan.' +param name string +param location string = resourceGroup().location +param tags object = {} + +param kind string = '' +param reserved bool = true +param sku object + +resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = { + name: name + location: location + tags: tags + sku: sku + kind: kind + properties: { + reserved: reserved + } +} + +output id string = appServicePlan.id +output name string = appServicePlan.name diff --git a/infra/core/host/functions.bicep b/infra/core/host/functions.bicep new file mode 100644 index 0000000..84acfbb --- /dev/null +++ b/infra/core/host/functions.bicep @@ -0,0 +1,87 @@ +metadata description = 'Creates an Azure Function in an existing Azure App Service plan.' +param name string +param location string = resourceGroup().location +param tags object = {} + +// Reference Properties +param applicationInsightsName string = '' +param appServicePlanId string +param keyVaultName string = '' +param managedIdentity bool = !empty(keyVaultName) +param storageAccountName string + +// Runtime Properties +@allowed([ + 'dotnet', 'dotnetcore', 'dotnet-isolated', 'node', 'python', 'java', 'powershell', 'custom' +]) +param runtimeName string +param runtimeNameAndVersion string = '${runtimeName}|${runtimeVersion}' +param runtimeVersion string + +// Function Settings +@allowed([ + '~4', '~3', '~2', '~1' +]) +param extensionVersion string = '~4' + +// Microsoft.Web/sites Properties +param kind string = 'functionapp,linux' + +// Microsoft.Web/sites/config +param allowedOrigins array = [] +param alwaysOn bool = true +param appCommandLine string = '' +@secure() +param appSettings object = {} +param clientAffinityEnabled bool = false +param enableOryxBuild bool = contains(kind, 'linux') +param functionAppScaleLimit int = -1 +param linuxFxVersion string = runtimeNameAndVersion +param minimumElasticInstanceCount int = -1 +param numberOfWorkers int = -1 +param scmDoBuildDuringDeployment bool = true +param use32BitWorkerProcess bool = false +param healthCheckPath string = '' + +module functions 'appservice.bicep' = { + name: '${name}-functions' + params: { + name: name + location: location + tags: tags + allowedOrigins: allowedOrigins + alwaysOn: alwaysOn + appCommandLine: appCommandLine + applicationInsightsName: applicationInsightsName + appServicePlanId: appServicePlanId + appSettings: union(appSettings, { + AzureWebJobsStorage: 'DefaultEndpointsProtocol=https;AccountName=${storage.name};AccountKey=${storage.listKeys().keys[0].value};EndpointSuffix=${environment().suffixes.storage}' + FUNCTIONS_EXTENSION_VERSION: extensionVersion + FUNCTIONS_WORKER_RUNTIME: runtimeName + }) + clientAffinityEnabled: clientAffinityEnabled + enableOryxBuild: enableOryxBuild + functionAppScaleLimit: functionAppScaleLimit + healthCheckPath: healthCheckPath + keyVaultName: keyVaultName + kind: kind + linuxFxVersion: linuxFxVersion + managedIdentity: managedIdentity + minimumElasticInstanceCount: minimumElasticInstanceCount + numberOfWorkers: numberOfWorkers + runtimeName: runtimeName + runtimeVersion: runtimeVersion + runtimeNameAndVersion: runtimeNameAndVersion + scmDoBuildDuringDeployment: scmDoBuildDuringDeployment + use32BitWorkerProcess: use32BitWorkerProcess + } +} + +resource storage 'Microsoft.Storage/storageAccounts@2021-09-01' existing = { + name: storageAccountName +} + +output identityPrincipalId string = managedIdentity ? functions.outputs.identityPrincipalId : '' +output name string = functions.outputs.name +output uri string = functions.outputs.uri +output id string = functions.outputs.id diff --git a/infra/core/host/staticwebapp.bicep b/infra/core/host/staticwebapp.bicep index 7bd695e..ad95054 100644 --- a/infra/core/host/staticwebapp.bicep +++ b/infra/core/host/staticwebapp.bicep @@ -1,11 +1,12 @@ metadata description = 'Creates an Azure Static Web Apps instance.' param name string +param rg string param location string = resourceGroup().location param tags object = {} param sku object = { - name: 'Free' - tier: 'Free' + name: 'Standard' + tier: 'Standard' } resource web 'Microsoft.Web/staticSites@2023-01-01' = { @@ -16,7 +17,27 @@ resource web 'Microsoft.Web/staticSites@2023-01-01' = { properties: { provider: 'Custom' } + identity: { + type: 'SystemAssigned' + } } +// resource backendResourceId 'Microsoft.Web/sites@2021-03-01' existing = { +// name: name +// scope: resourceGroup(rg) +// } + +// resource swamv_ui_backend_functions 'Microsoft.Web/staticSites/linkedBackends@2022-03-01' = { +// parent: web +// name: 'swa_backend_functions' +// properties: { +// backendResourceId: backendResourceId.id +// region: location +// } +// } + output name string = web.name output uri string = 'https://${web.properties.defaultHostname}' +output identityPrincipalId string = web.identity.principalId +#disable-next-line outputs-should-not-contain-secrets +output DEPLOYMENT_TOKEN string = web.listSecrets(web.apiVersion).properties.apiKey diff --git a/infra/core/search/search-services.bicep b/infra/core/search/search-services.bicep deleted file mode 100644 index 33fd83e..0000000 --- a/infra/core/search/search-services.bicep +++ /dev/null @@ -1,68 +0,0 @@ -metadata description = 'Creates an Azure AI Search instance.' -param name string -param location string = resourceGroup().location -param tags object = {} - -param sku object = { - name: 'standard' -} - -param authOptions object = {} -param disableLocalAuth bool = false -param disabledDataExfiltrationOptions array = [] -param encryptionWithCmk object = { - enforcement: 'Unspecified' -} -@allowed([ - 'default' - 'highDensity' -]) -param hostingMode string = 'default' -param networkRuleSet object = { - bypass: 'None' - ipRules: [] -} -param partitionCount int = 1 -@allowed([ - 'enabled' - 'disabled' -]) -param publicNetworkAccess string = 'enabled' -param replicaCount int = 1 -@allowed([ - 'disabled' - 'free' - 'standard' -]) -param semanticSearch string = 'disabled' - -var searchIdentityProvider = (sku.name == 'free') ? null : { - type: 'SystemAssigned' -} - -resource search 'Microsoft.Search/searchServices@2021-04-01-preview' = { - name: name - location: location - tags: tags - // The free tier does not support managed identity - identity: searchIdentityProvider - properties: { - authOptions: disableLocalAuth ? null : authOptions - disableLocalAuth: disableLocalAuth - disabledDataExfiltrationOptions: disabledDataExfiltrationOptions - encryptionWithCmk: encryptionWithCmk - hostingMode: hostingMode - networkRuleSet: networkRuleSet - partitionCount: partitionCount - publicNetworkAccess: publicNetworkAccess - replicaCount: replicaCount - semanticSearch: semanticSearch - } - sku: sku -} - -output id string = search.id -output endpoint string = 'https://${name}.search.windows.net/' -output name string = search.name -output principalId string = !empty(searchIdentityProvider) ? search.identity.principalId : '' - diff --git a/infra/main.bicep b/infra/main.bicep index c21b590..65e3972 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -11,43 +11,30 @@ param location string param resourceGroupName string = '' param webappName string = 'webapp' +param apiServiceName string = 'api' +param appServicePlanName string = '' param storageAccountName string = '' -var abbrs = loadJsonContent('abbreviations.json') -var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) -var tags = { 'azd-env-name': environmentName } +param blobContainerName string = 'files' param webappLocation string // Set in main.parameters.json -param searchServiceName string = '' - -// OpenAI Cognitive Services -param chatModelName string // Set in main.parameters.json -param chatDeploymentName string = chatModelName -param chatModelVersion string // Set in main.parameters.json -param chatDeploymentCapacity int = 30 -param embeddingsModelName string // Set in main.parameters.json -param embeddingsModelVersion string // Set in main.parameters.json -param embeddingsDeploymentName string = embeddingsModelName -param embeddingsDeploymentCapacity int = 30 +// Azure OpenAI -- Cognitive Services +param assistantId string // Set in main.parameters.json -var finalOpenAiUrl = empty(openAiUrl) ? 'https://${openAi.outputs.name}.openai.azure.com' : openAiUrl -var storageUrl = 'https://${storage.outputs.name}.blob.${environment().suffixes.storage}' -var searchUrl = 'https://${search.outputs.name}.search.windows.net' - -// The free tier does not support managed identity (required) or semantic search (optional) -@allowed(['basic', 'standard', 'standard2', 'standard3', 'storage_optimized_l1', 'storage_optimized_l2']) -param searchServiceSkuName string +var assistantGpt = { + modelName: 'gpt-35-turbo' + deploymentName: 'gpt-35-turbo' + deploymentVersion: '1106' + deploymentCapacity: 120 +} param openAiLocation string // Set in main.parameters.json param openAiSkuName string = 'S0' param openAiUrl string = '' -param blobContainerName string = 'files' - -// Id of the user or app to assign application roles -param principalId string = '' - -// Set automated deployment flag -param isContinuousDeployment bool // Set in main.parameters.json +var finalOpenAiUrl = empty(openAiUrl) ? 'https://${openAi.outputs.name}.openai.azure.com' : openAiUrl +var abbrs = loadJsonContent('abbreviations.json') +var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) +var tags = { 'azd-env-name': environmentName } // Organize resources in a resource group resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { @@ -58,30 +45,55 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { // The application frontend webapp module webapp './core/host/staticwebapp.bicep' = { - name: 'webapp' + dependsOn: [api] + name: '${abbrs.webStaticSites}web-${resourceToken}' scope: resourceGroup params: { name: !empty(webappName) ? webappName : '${abbrs.webStaticSites}web-${resourceToken}' location: webappLocation tags: union(tags, { 'azd-service-name': webappName }) + rg: resourceGroup.name + } +} + +// The application backend API +module api './core/host/functions.bicep' = { + name: 'api' + scope: resourceGroup + params: { + name: '${abbrs.webSitesFunctions}api-${resourceToken}' + location: location + tags: union(tags, { 'azd-service-name': apiServiceName }) + alwaysOn: false + runtimeName: 'node' + runtimeVersion: '20' + appServicePlanId: appServicePlan.outputs.id + storageAccountName: storage.outputs.name + managedIdentity: true + appSettings: { + AZURE_OPENAI_API_ENDPOINT: finalOpenAiUrl + AZURE_OPENAI_API_DEPLOYMENT_NAME: assistantGpt.deploymentName + } } + dependsOn: empty(openAiUrl) ? [] : [openAi] } -module search 'core/search/search-services.bicep' = { - name: 'search' +// Compute plan for the Azure Functions API +module appServicePlan './core/host/appserviceplan.bicep' = { + name: 'appserviceplan' scope: resourceGroup params: { - name: !empty(searchServiceName) ? searchServiceName : '${abbrs.searchSearchServices}${resourceToken}' + name: !empty(appServicePlanName) ? appServicePlanName : '${abbrs.webServerFarms}${resourceToken}' location: location tags: tags - disableLocalAuth: true - authOptions: null sku: { - name: searchServiceSkuName + name: 'Y1' + tier: 'Dynamic' } } } -// Storage for Azure Functions API and Blob storage + +// Storage for Azure Functions API module storage './core/storage/storage-account.bicep' = { name: 'storage' scope: resourceGroup @@ -112,50 +124,54 @@ module openAi 'core/ai/cognitiveservices.bicep' = if (empty(openAiUrl)) { disableLocalAuth: true deployments: [ { - name: chatDeploymentName + name: assistantGpt.deploymentName model: { format: 'OpenAI' - name: chatModelName - version: chatModelVersion + name: assistantGpt.modelName + version: assistantGpt.deploymentVersion } sku: { name: 'Standard' - capacity: chatDeploymentCapacity - } - } - { - name: embeddingsDeploymentName - model: { - format: 'OpenAI' - name: embeddingsModelName - version: embeddingsModelVersion + capacity: assistantGpt.deploymentCapacity } - capacity: embeddingsDeploymentCapacity } ] } } -// User roles -module openAiRoleUser 'core/security/role.bicep' = if (!isContinuousDeployment) { +// Roles + +// System roles +module openAiRoleApi 'core/security/role.bicep' = { scope: resourceGroup - name: 'openai-role-user' + name: 'openai-role-api' params: { - principalId: principalId + principalId: api.outputs.identityPrincipalId // Cognitive Services OpenAI User roleDefinitionId: '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' - principalType: 'User' + principalType: 'ServicePrincipal' } } -module storageRoleUser 'core/security/role.bicep' = if (!isContinuousDeployment) { +module storageRoleApi 'core/security/role.bicep' = { scope: resourceGroup - name: 'storage-contrib-role-user' + name: 'storage-role-api' params: { - principalId: principalId + principalId: api.outputs.identityPrincipalId // Storage Blob Data Contributor roleDefinitionId: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' - principalType: 'User' + principalType: 'ServicePrincipal' + } +} + +module openAiRoleOpenAi 'core/security/role.bicep' = { + scope: resourceGroup + name: 'openai-role-openAi' + params: { + principalId: openAi.outputs.identityPrincipalId + // Cognitive Services OpenAI User + roleDefinitionId: '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' + principalType: 'ServicePrincipal' } } @@ -163,15 +179,9 @@ output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId output AZURE_RESOURCE_GROUP string = resourceGroup.name -output AZURE_OPENAI_API_ENDPOINT string = finalOpenAiUrl -output AZURE_OPENAI_API_DEPLOYMENT_NAME string = chatDeploymentName -output AZURE_OPENAI_API_MODEL string = chatModelName -output AZURE_OPENAI_API_MODEL_VERSION string = chatModelVersion -output AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME string = embeddingsDeploymentName -output AZURE_OPENAI_API_EMBEDDINGS_MODEL string = embeddingsModelName -output AZURE_OPENAI_API_EMBEDDINGS_MODEL_VERSION string = embeddingsModelVersion -output AZURE_STORAGE_URL string = storageUrl -output AZURE_STORAGE_CONTAINER_NAME string = blobContainerName -output AZURE_AISEARCH_ENDPOINT string = searchUrl +output AZURE_OPENAI_ENDPOINT string = finalOpenAiUrl +output AZURE_DEPLOYMENT_NAME string = assistantGpt.deploymentName +output ASSISTANT_ID string = assistantId output WEBAPP_URL string = webapp.outputs.uri +output DEPLOYMENT_TOKEN string = webapp.outputs.DEPLOYMENT_TOKEN diff --git a/infra/main.parameters.json b/infra/main.parameters.json index bfee8af..a70ef6c 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -17,26 +17,17 @@ "openAiLocation": { "value": "${AZURE_OPENAI_LOCATION=swedencentral}" }, - "chatModelName": { - "value": "${AZURE_OPENAI_API_MODEL=gpt-35-turbo}" - }, - "chatModelVersion": { - "value": "${AZURE_OPENAI_API_MODEL_VERSION=1106}" - }, - "embeddingsModelName": { - "value": "${AZURE_OPENAI_API_EMBEDDINGS_MODEL=text-embedding-ada-002}" - }, - "embeddingsModelVersion": { - "value": "${AZURE_OPENAI_API_EMBEDDINGS_MODEL_VERSION=2}" - }, "webappLocation": { "value": "${AZURE_WEBAPP_LOCATION=eastus2}" }, - "searchServiceSkuName": { - "value": "${AZURE_SEARCH_SERVICE_SKU=basic}" - }, "isContinuousDeployment": { "value": "${CI=false}" + }, + "assistantId": { + "value": "${ASSISTANT_ID=?}" + }, + "azureDeploymentName": { + "value": "${AZURE_DEPLOYMENT_NAME=gpt-35-turbo}" } } } diff --git a/swa-cli.config.json b/swa-cli.config.json index a696da6..05acaf6 100644 --- a/swa-cli.config.json +++ b/swa-cli.config.json @@ -3,16 +3,16 @@ "configurations": { "azure-openai-assistant-javascript": { "appLocation": "src", - "apiLocation": "api", - "outputLocation": "/dist", + "apiLocation": "", + "outputLocation": "dist", "apiLanguage": "node", "apiVersion": "18", "appBuildCommand": "npm run build", "apiBuildCommand": "npm run build --if-present", "run": "npm run dev", "appDevserverUrl": "http://localhost:5173", - "appName": "azure-openai-assistant-javascript", - "resourceGroup": "azure-openai-assistant-javascript-rg" + "env": "default", + "appName": "webapp" } } } \ No newline at end of file