diff --git a/.gitignore b/.gitignore
index 3c3f4e6..78a9f71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -261,4 +261,9 @@ paket-files/
# Python Tools for Visual Studio (PTVS)
__pycache__/
-*.pyc
\ No newline at end of file
+*.pyc
+
+# Environment variables
+.env
+
+.azure
\ No newline at end of file
diff --git a/README.md b/README.md
index d8246d3..c693747 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,9 @@
# aks-docs-gpt-chat
A GPT Chat application for Azure Kubernetes Service Documentation
+## Deploy
+
+- Using the Azure Developer CLI
## Application Diagram
diff --git a/aks-docs-gpt-chat.sln b/aks-docs-gpt-chat.sln
new file mode 100644
index 0000000..60a4bdf
--- /dev/null
+++ b/aks-docs-gpt-chat.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.002.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AksChatBot", "src\AksChatBot.csproj", "{054E6CFD-3E6D-49F2-8E52-43E302056DC1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {054E6CFD-3E6D-49F2-8E52-43E302056DC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {054E6CFD-3E6D-49F2-8E52-43E302056DC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {054E6CFD-3E6D-49F2-8E52-43E302056DC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {054E6CFD-3E6D-49F2-8E52-43E302056DC1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {03C59C30-345F-4D4B-923D-CC3E563B6A00}
+ EndGlobalSection
+EndGlobal
diff --git a/azure.yaml b/azure.yaml
new file mode 100644
index 0000000..a3c8760
--- /dev/null
+++ b/azure.yaml
@@ -0,0 +1,8 @@
+name: gbb-aks-llm-chat-bot
+metadata:
+ template: gbb-aks-llm-chat-bot@0.0.1-beta
+services:
+ api:
+ project: ./src
+ language: dotnet
+ host: appservice
\ No newline at end of file
diff --git a/infra/ai/cognitive-services.bicep b/infra/ai/cognitive-services.bicep
new file mode 100644
index 0000000..e69de29
diff --git a/infra/app/app-service-app-settings.bicep b/infra/app/app-service-app-settings.bicep
new file mode 100644
index 0000000..f4b22f8
--- /dev/null
+++ b/infra/app/app-service-app-settings.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/app/app-service-plan.bicep b/infra/app/app-service-plan.bicep
new file mode 100644
index 0000000..2e37e04
--- /dev/null
+++ b/infra/app/app-service-plan.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/app/app-service.bicep b/infra/app/app-service.bicep
new file mode 100644
index 0000000..957a431
--- /dev/null
+++ b/infra/app/app-service.bicep
@@ -0,0 +1,118 @@
+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 configLogs 'config' = {
+ name: 'logs'
+ properties: {
+ applicationLogs: { fileSystem: { level: 'Verbose' } }
+ detailedErrorMessages: { enabled: true }
+ failedRequestsTracing: { enabled: true }
+ httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } }
+ }
+ }
+
+ resource basicPublishingCredentialsPoliciesFtp 'basicPublishingCredentialsPolicies' = {
+ name: 'ftp'
+ properties: {
+ allow: false
+ }
+ }
+
+ resource basicPublishingCredentialsPoliciesScm 'basicPublishingCredentialsPolicies' = {
+ name: 'scm'
+ properties: {
+ allow: false
+ }
+ }
+}
+
+module config './app-service-app-settings.bicep' = if (!empty(appSettings)) {
+ 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 } : {})
+ }
+}
+
+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}'
diff --git a/infra/app/container-registry.bicep b/infra/app/container-registry.bicep
new file mode 100644
index 0000000..e69de29
diff --git a/infra/data/cognitive-search.bicep b/infra/data/cognitive-search.bicep
new file mode 100644
index 0000000..e69de29
diff --git a/infra/main.bicep b/infra/main.bicep
new file mode 100644
index 0000000..56b71d3
--- /dev/null
+++ b/infra/main.bicep
@@ -0,0 +1,65 @@
+targetScope = 'subscription'
+
+@minLength(3)
+@maxLength(3)
+@description('A prefix string to generate a short unique hash used in all resources.')
+param prefix string = 'gbb'
+
+@minLength(4)
+@description('Primary location for all resources')
+param location string = 'eastus2'
+
+@description('Resource Group to deploy all resources to')
+param resourceGroupName string = '${prefix}-rg'
+
+@description('Name of the App Service Plan to create')
+param appServicePlanName string = ''
+
+@description('Name of the API Service to create')
+param apiServiceName string = ''
+
+// @description('Name of the front end UI app to create')
+// param frontEndName string = 'frontend'
+
+var resourceToken = toLower(uniqueString(subscription().id, prefix, location))
+
+// Organize resources in a resource group
+resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
+ name: resourceGroupName
+ location: location
+}
+
+// Create an App Service Plan to group applications under the same payment plan and SKU
+module appServicePlan './app/app-service-plan.bicep' = {
+ name: 'appserviceplan'
+ scope: rg
+ params: {
+ name: !empty(appServicePlanName) ? appServicePlanName : resourceToken
+ location: location
+ sku: {
+ name: 'B1'
+ }
+ }
+}
+
+module appService './app/app-service.bicep' = {
+ name: 'appservice'
+ scope: rg
+ dependsOn: [
+ appServicePlan
+ ]
+ params: {
+ name: !empty(apiServiceName) ? apiServiceName : resourceToken
+ location: location
+ appServicePlanId: appServicePlan.outputs.id
+ runtimeName: 'dotnet-isolated'
+ runtimeVersion: '7.0'
+ tags: {
+ 'azd-service-name': apiServiceName
+ }
+ }
+}
+
+// Data outputs
+output AZURE_LOCATION string = location
+output AZURE_TENANT_ID string = tenant().tenantId
diff --git a/infra/main.parameters.json b/infra/main.parameters.json
new file mode 100644
index 0000000..dee1bec
--- /dev/null
+++ b/infra/main.parameters.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "environmentName": {
+ "value": "${AZURE_ENV_NAME}"
+ },
+ "location": {
+ "value": "${AZURE_LOCATION}"
+ },
+ "principalId": {
+ "value": "${AZURE_PRINCIPAL_ID}"
+ }
+ }
+ }
\ No newline at end of file
diff --git a/rest-samples/query-aks.http b/rest-samples/query-aks.http
index 925d1e2..7d29ca9 100644
--- a/rest-samples/query-aks.http
+++ b/rest-samples/query-aks.http
@@ -1,4 +1,4 @@
-POST http://localhost:7071/api/Chat
+POST http://localhost:8080/api/Chat
Content-Type: application/json
{
diff --git a/src/.dockerignore b/src/.dockerignore
index 1927772..976dca8 100644
--- a/src/.dockerignore
+++ b/src/.dockerignore
@@ -1 +1,2 @@
-local.settings.json
\ No newline at end of file
+local.settings.json
+.env
\ No newline at end of file
diff --git a/src/AksChatBot.csproj b/src/AksChatBot.csproj
index 3a07da8..b4e16cd 100644
--- a/src/AksChatBot.csproj
+++ b/src/AksChatBot.csproj
@@ -5,6 +5,7 @@
Exe
enable
enable
+ 837887e9-bab1-40c9-8261-3f8ca0d1c5a0