diff --git a/App/backend-api/Microsoft.GS.DPS.Host/AppConfiguration/AppConfiguration.cs b/App/backend-api/Microsoft.GS.DPS.Host/AppConfiguration/AppConfiguration.cs index 5bd0dc92..41ab143a 100644 --- a/App/backend-api/Microsoft.GS.DPS.Host/AppConfiguration/AppConfiguration.cs +++ b/App/backend-api/Microsoft.GS.DPS.Host/AppConfiguration/AppConfiguration.cs @@ -1,6 +1,7 @@ using Azure.Identity; using Microsoft.Extensions.Azure; using Microsoft.GS.DPSHost.AppConfiguration; +using Microsoft.GS.DPSHost.Helpers; namespace Microsoft.GS.DPSHost.AppConfiguration { @@ -11,12 +12,13 @@ public static void Config(IHostApplicationBuilder builder) //Read ServiceConfiguration files - appsettings.json / appsettings.Development.json //builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); //builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true); - + var servicesConfig = builder.Configuration.GetSection("Application:Services").Get(); + string appEnv = servicesConfig?.APP_ENV; //Read AppConfiguration with managed Identity builder.Configuration.AddAzureAppConfiguration(options => { - options.Connect(new Uri(builder.Configuration["ConnectionStrings:AppConfig"]), new DefaultAzureCredential()); + options.Connect(new Uri(builder.Configuration["ConnectionStrings:AppConfig"]), AzureCredentialHelper.GetAzureCredential(appEnv)); }); //Read ServiceConfiguration diff --git a/App/backend-api/Microsoft.GS.DPS.Host/AppConfiguration/Services.cs b/App/backend-api/Microsoft.GS.DPS.Host/AppConfiguration/Services.cs index c55cc9f8..f68aaa30 100644 --- a/App/backend-api/Microsoft.GS.DPS.Host/AppConfiguration/Services.cs +++ b/App/backend-api/Microsoft.GS.DPS.Host/AppConfiguration/Services.cs @@ -6,6 +6,7 @@ public class Services public KernelMemoryConfig KernelMemory { get; set; } public PersistentStorageConfig PersistentStorage { get; set; } public AzureAISearchConfig AzureAISearch { get; set; } + public string APP_ENV { get; set; } public class AzureAISearchConfig { diff --git a/App/backend-api/Microsoft.GS.DPS.Host/Helpers/azure_credential_utils.cs b/App/backend-api/Microsoft.GS.DPS.Host/Helpers/azure_credential_utils.cs new file mode 100644 index 00000000..6439cca3 --- /dev/null +++ b/App/backend-api/Microsoft.GS.DPS.Host/Helpers/azure_credential_utils.cs @@ -0,0 +1,32 @@ +using System; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Identity; + +namespace Microsoft.GS.DPSHost.Helpers +{ + public static class AzureCredentialHelper + { + public static TokenCredential GetAzureCredential(string appEnv = "prod", string clientId = null) + { + //var env = Environment.GetEnvironmentVariable("APP_ENV") ?? "prod"; + Console.WriteLine($"Current APP_ENV: {appEnv}"); + + if (string.Equals(appEnv, "dev", StringComparison.OrdinalIgnoreCase)) + { + return new DefaultAzureCredential(); // For local development + } + else + { + return clientId != null + ? new ManagedIdentityCredential(clientId) + : new ManagedIdentityCredential(); + } + } + + public static Task GetAzureCredentialAsync(string appEnv = "prod", string clientId = null) + { + return Task.FromResult(GetAzureCredential(appEnv, clientId)); + } + } +} diff --git a/App/backend-api/Microsoft.GS.DPS.Host/appsettings.json b/App/backend-api/Microsoft.GS.DPS.Host/appsettings.json index a6fbb98b..e00d9704 100644 --- a/App/backend-api/Microsoft.GS.DPS.Host/appsettings.json +++ b/App/backend-api/Microsoft.GS.DPS.Host/appsettings.json @@ -28,15 +28,16 @@ } }, "Services": { - "CognitiveService": { - "DocumentIntelligence": { - "Endpoint": "", - "APIKey": "" - } - }, - "KernelMemory": { - "Endpoint": "" - } + "CognitiveService": { + "DocumentIntelligence": { + "Endpoint": "", + "APIKey": "" + } + }, + "KernelMemory": { + "Endpoint": "" + }, + "APP_ENV": "prod" } } } diff --git a/App/kernel-memory/Directory.Packages.props b/App/kernel-memory/Directory.Packages.props index 3f6e364b..670d633b 100644 --- a/App/kernel-memory/Directory.Packages.props +++ b/App/kernel-memory/Directory.Packages.props @@ -7,7 +7,7 @@ - + diff --git a/App/kernel-memory/Helpers/Helpers.csproj b/App/kernel-memory/Helpers/Helpers.csproj new file mode 100644 index 00000000..4296f400 --- /dev/null +++ b/App/kernel-memory/Helpers/Helpers.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + + + + + + + + diff --git a/App/kernel-memory/Helpers/azure_credential_utils.cs b/App/kernel-memory/Helpers/azure_credential_utils.cs new file mode 100644 index 00000000..de1f00d9 --- /dev/null +++ b/App/kernel-memory/Helpers/azure_credential_utils.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft. All rights reserved. +using System; +using System.Reflection.PortableExecutable; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Identity; +namespace Helpers; + +public class azure_credential_utils +{ + public static TokenCredential GetAzureCredential(string appEnv = "prod", string clientId = null) + { + //var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"; + + if (string.Equals(appEnv, "dev", StringComparison.OrdinalIgnoreCase)) + { + return new DefaultAzureCredential(); // For local development + } + else + { + return clientId != null + ? new ManagedIdentityCredential(clientId) + : new ManagedIdentityCredential(); + } + } + + public static Task GetAzureCredentialAsync(string appEnv = "prod", string clientId = null) + { + return Task.FromResult(GetAzureCredential(appEnv, clientId)); + } +} \ No newline at end of file diff --git a/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntel.csproj b/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntel.csproj index f309652d..7ef4208a 100644 --- a/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntel.csproj +++ b/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntel.csproj @@ -8,10 +8,6 @@ $(NoWarn);KMEXP02;CA1724;CA1308; - - - - @@ -30,4 +26,9 @@ + + + + + diff --git a/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntelConfig.cs b/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntelConfig.cs index f6a05883..99ba7502 100644 --- a/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntelConfig.cs +++ b/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntelConfig.cs @@ -23,6 +23,8 @@ public enum AuthTypes public string APIKey { get; set; } = string.Empty; + public string APP_ENV { get; set; } = "prod"; + /// /// Verify that the current state is valid. /// diff --git a/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntelEngine.cs b/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntelEngine.cs index 49f3c2a7..6d824c95 100644 --- a/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntelEngine.cs +++ b/App/kernel-memory/extensions/AzureAIDocIntel/AzureAIDocIntelEngine.cs @@ -8,8 +8,11 @@ using Azure; using Azure.AI.FormRecognizer.DocumentAnalysis; using Azure.Identity; +using Helpers; using Microsoft.Extensions.Logging; using Microsoft.KernelMemory.Diagnostics; +using Microsoft.KernelMemory.Configuration; + namespace Microsoft.KernelMemory.DataFormats.AzureAIDocIntel; @@ -36,7 +39,7 @@ public AzureAIDocIntelEngine( switch (config.Auth) { case AzureAIDocIntelConfig.AuthTypes.AzureIdentity: - this._recognizerClient = new DocumentAnalysisClient(new Uri(config.Endpoint), new DefaultAzureCredential()); + this._recognizerClient = new DocumentAnalysisClient(new Uri(config.Endpoint), azure_credential_utils.GetAzureCredential(config.APP_ENV)); break; case AzureAIDocIntelConfig.AuthTypes.APIKey: diff --git a/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearch.csproj b/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearch.csproj index c4126a22..39fa86d0 100644 --- a/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearch.csproj +++ b/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearch.csproj @@ -9,6 +9,7 @@ + diff --git a/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearchConfig.cs b/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearchConfig.cs index d9023ab6..44b03d74 100644 --- a/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearchConfig.cs +++ b/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearchConfig.cs @@ -25,6 +25,8 @@ public enum AuthTypes public string Endpoint { get; set; } = string.Empty; public string APIKey { get; set; } = string.Empty; + public string APP_ENV { get; set; } = "prod"; + /// /// Important: when using hybrid search, relevance scores /// are very different (e.g. lower) from when using just vector search. diff --git a/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearchMemory.cs b/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearchMemory.cs index 07dfde26..b99a2baa 100644 --- a/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearchMemory.cs +++ b/App/kernel-memory/extensions/AzureAISearch/AzureAISearch/AzureAISearchMemory.cs @@ -14,6 +14,7 @@ using Azure.Search.Documents.Indexes; using Azure.Search.Documents.Indexes.Models; using Azure.Search.Documents.Models; +using Helpers; using Microsoft.Extensions.Logging; using Microsoft.KernelMemory.AI; using Microsoft.KernelMemory.Diagnostics; @@ -66,7 +67,7 @@ public AzureAISearchMemory( case AzureAISearchConfig.AuthTypes.AzureIdentity: this._adminClient = new SearchIndexClient( new Uri(config.Endpoint), - new DefaultAzureCredential(), + azure_credential_utils.GetAzureCredential(config.APP_ENV), GetClientOptions()); break; diff --git a/App/kernel-memory/extensions/AzureBlobs/AzureBlobs.csproj b/App/kernel-memory/extensions/AzureBlobs/AzureBlobs.csproj index cded11be..07d5694e 100644 --- a/App/kernel-memory/extensions/AzureBlobs/AzureBlobs.csproj +++ b/App/kernel-memory/extensions/AzureBlobs/AzureBlobs.csproj @@ -9,6 +9,7 @@ + diff --git a/App/kernel-memory/extensions/AzureBlobs/AzureBlobsConfig.cs b/App/kernel-memory/extensions/AzureBlobs/AzureBlobsConfig.cs index 109e0019..ed61616e 100644 --- a/App/kernel-memory/extensions/AzureBlobs/AzureBlobsConfig.cs +++ b/App/kernel-memory/extensions/AzureBlobs/AzureBlobsConfig.cs @@ -35,6 +35,8 @@ public enum AuthTypes public string EndpointSuffix { get; set; } = "core.windows.net"; public string Container { get; set; } = ""; + public string APP_ENV { get; set; } = "prod"; + public void SetCredential(StorageSharedKeyCredential credential) { this.Auth = AuthTypes.ManualStorageSharedKeyCredential; diff --git a/App/kernel-memory/extensions/AzureBlobs/AzureBlobsStorage.cs b/App/kernel-memory/extensions/AzureBlobs/AzureBlobsStorage.cs index 993bc2a8..109e7999 100644 --- a/App/kernel-memory/extensions/AzureBlobs/AzureBlobsStorage.cs +++ b/App/kernel-memory/extensions/AzureBlobs/AzureBlobsStorage.cs @@ -11,6 +11,7 @@ using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using Azure.Storage.Blobs.Specialized; +using Helpers; using Microsoft.Extensions.Logging; using Microsoft.KernelMemory.Diagnostics; using Microsoft.KernelMemory.Pipeline; @@ -61,7 +62,7 @@ public AzureBlobsStorage( { this.ValidateAccountName(config.Account); var suffix = this.ValidateEndpointSuffix(config.EndpointSuffix); - client = new BlobServiceClient(new Uri($"https://{config.Account}.blob.{suffix}"), new DefaultAzureCredential()); + client = new BlobServiceClient(new Uri($"https://{config.Account}.blob.{suffix}"), azure_credential_utils.GetAzureCredential(config.APP_ENV)); break; } diff --git a/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAI.csproj b/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAI.csproj index b3163ddd..5fea3398 100644 --- a/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAI.csproj +++ b/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAI.csproj @@ -9,6 +9,7 @@ + diff --git a/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAIConfig.cs b/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAIConfig.cs index 993b6598..caf7f493 100644 --- a/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAIConfig.cs +++ b/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAIConfig.cs @@ -52,6 +52,8 @@ public enum APITypes /// public string Endpoint { get; set; } = string.Empty; + public string APP_ENV { get; set; } = "prod"; + /// /// Azure OpenAI deployment name /// diff --git a/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAITextEmbeddingGenerator.cs b/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAITextEmbeddingGenerator.cs index 4e1ca1e5..784be4b7 100644 --- a/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAITextEmbeddingGenerator.cs +++ b/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAITextEmbeddingGenerator.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Azure.Identity; +using Helpers; using Microsoft.Extensions.Logging; using Microsoft.KernelMemory.AI.OpenAI; using Microsoft.KernelMemory.Diagnostics; @@ -52,7 +53,7 @@ public AzureOpenAITextEmbeddingGenerator( this._client = new AzureOpenAITextEmbeddingGenerationService( deploymentName: config.Deployment, endpoint: config.Endpoint, - credential: new DefaultAzureCredential(), + credential: azure_credential_utils.GetAzureCredential(config.APP_ENV), modelId: config.Deployment, httpClient: httpClient, dimensions: config.EmbeddingDimensions, diff --git a/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAITextGenerator.cs b/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAITextGenerator.cs index bd0a1b52..8eac9a73 100644 --- a/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAITextGenerator.cs +++ b/App/kernel-memory/extensions/AzureOpenAI/AzureOpenAITextGenerator.cs @@ -11,6 +11,7 @@ using Azure.AI.OpenAI; using Azure.Core.Pipeline; using Azure.Identity; +using Helpers; using Microsoft.Extensions.Logging; using Microsoft.KernelMemory.AI.AzureOpenAI.Internals; using Microsoft.KernelMemory.AI.OpenAI; @@ -77,7 +78,7 @@ public AzureOpenAITextGenerator( switch (config.Auth) { case AzureOpenAIConfig.AuthTypes.AzureIdentity: - this._client = new OpenAIClient(new Uri(config.Endpoint), new DefaultAzureCredential(), options); + this._client = new OpenAIClient(new Uri(config.Endpoint), azure_credential_utils.GetAzureCredential(config.APP_ENV), options); break; case AzureOpenAIConfig.AuthTypes.ManualTokenCredential: diff --git a/App/kernel-memory/extensions/AzureQueues/AzureQueues.csproj b/App/kernel-memory/extensions/AzureQueues/AzureQueues.csproj index 35e1a148..ed448406 100644 --- a/App/kernel-memory/extensions/AzureQueues/AzureQueues.csproj +++ b/App/kernel-memory/extensions/AzureQueues/AzureQueues.csproj @@ -9,6 +9,7 @@ + diff --git a/App/kernel-memory/extensions/AzureQueues/AzureQueuesConfig.cs b/App/kernel-memory/extensions/AzureQueues/AzureQueuesConfig.cs index c357a9f8..3b4a8e30 100644 --- a/App/kernel-memory/extensions/AzureQueues/AzureQueuesConfig.cs +++ b/App/kernel-memory/extensions/AzureQueues/AzureQueuesConfig.cs @@ -37,6 +37,8 @@ public enum AuthTypes public string AccountKey { get; set; } = ""; public string EndpointSuffix { get; set; } = "core.windows.net"; + public string APP_ENV { get; set; } = "prod"; + /// /// How often to check if there are new messages. /// diff --git a/App/kernel-memory/extensions/AzureQueues/AzureQueuesPipeline.cs b/App/kernel-memory/extensions/AzureQueues/AzureQueuesPipeline.cs index fdf56701..ea286f82 100644 --- a/App/kernel-memory/extensions/AzureQueues/AzureQueuesPipeline.cs +++ b/App/kernel-memory/extensions/AzureQueues/AzureQueuesPipeline.cs @@ -11,6 +11,7 @@ using Azure.Storage; using Azure.Storage.Queues; using Azure.Storage.Queues.Models; +using Helpers; using Microsoft.Extensions.Logging; using Microsoft.KernelMemory.Diagnostics; using Microsoft.KernelMemory.DocumentStorage; @@ -94,7 +95,7 @@ public AzureQueuesPipeline( { this.ValidateAccountName(config.Account); var suffix = this.ValidateEndpointSuffix(config.EndpointSuffix); - this._clientBuilder = queueName => new QueueClient(new($"https://{config.Account}.queue.{suffix}/{queueName}"), new DefaultAzureCredential()); + this._clientBuilder = queueName => new QueueClient(new($"https://{config.Account}.queue.{suffix}/{queueName}"), azure_credential_utils.GetAzureCredential(config.APP_ENV)); break; } diff --git a/App/kernel-memory/infra/modules/container-app.bicep b/App/kernel-memory/infra/modules/container-app.bicep index 015c2105..ff478b0a 100644 --- a/App/kernel-memory/infra/modules/container-app.bicep +++ b/App/kernel-memory/infra/modules/container-app.bicep @@ -172,6 +172,10 @@ resource kmService 'Microsoft.App/containerApps@2023-05-01' = { name: 'KernelMemory__Services__AzureAIDocIntel__Endpoint' value: AzureAIDocIntel_Endpoint } + { + name: 'APP_ENV' + value: 'prod' + } ] } ] diff --git a/App/kernel-memory/service/Core/Configuration/KernelMemoryConfig.cs b/App/kernel-memory/service/Core/Configuration/KernelMemoryConfig.cs index f1b5b62e..20709c0d 100644 --- a/App/kernel-memory/service/Core/Configuration/KernelMemoryConfig.cs +++ b/App/kernel-memory/service/Core/Configuration/KernelMemoryConfig.cs @@ -162,6 +162,8 @@ public string ContentStorageType /// public string DefaultIndexName { get; set; } = "default"; + public string APP_ENV { get; set; } = "prod"; + /// /// HTTP service authorization settings. /// diff --git a/App/kernel-memory/service/Service/Program.cs b/App/kernel-memory/service/Service/Program.cs index 8e2b2b5c..993e49d3 100644 --- a/App/kernel-memory/service/Service/Program.cs +++ b/App/kernel-memory/service/Service/Program.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using Azure.Identity; +using Helpers; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; @@ -20,6 +21,7 @@ using Microsoft.KernelMemory.Pipeline; using Microsoft.KernelMemory.Service.AspNetCore; + // KM Configuration: // // * Settings are loaded at runtime from multiple sources, merging values. @@ -82,10 +84,13 @@ public static void Main(string[] args) appBuilder.Configuration.AddKMConfigurationSources(); + var servicesConfig = appBuilder.Configuration.GetSection("KernelMemory").Get(); + string appEnv = servicesConfig?.APP_ENV; + // Add Configuration from App Configuration Service appBuilder.Configuration.AddAzureAppConfiguration(options => { - options.Connect(new Uri(appBuilder.Configuration["ConnectionStrings:AppConfig"]), new DefaultAzureCredential()); + options.Connect(new Uri(appBuilder.Configuration["ConnectionStrings:AppConfig"]), azure_credential_utils.GetAzureCredential(appEnv: appEnv)); }); diff --git a/App/kernel-memory/service/Service/appsettings.json b/App/kernel-memory/service/Service/appsettings.json index 4dc741c1..b5a8ff95 100644 --- a/App/kernel-memory/service/Service/appsettings.json +++ b/App/kernel-memory/service/Service/appsettings.json @@ -465,7 +465,8 @@ "MemoryTableName": "KMMemories", "EmbeddingsTableName": "KMEmbeddings", "TagsTableName": "KMMemoriesTags" - } + }, + "APP_ENV": "prod" } } } diff --git a/Deployment/appconfig/aiservice/appconfig.jsonl b/Deployment/appconfig/aiservice/appconfig.jsonl index 6066134f..ce11e2c5 100644 --- a/Deployment/appconfig/aiservice/appconfig.jsonl +++ b/Deployment/appconfig/aiservice/appconfig.jsonl @@ -18,6 +18,7 @@ "Application:Services:PersistentStorage:CosmosMongo:ConnectionString": "{cosmosmongo-connection-string}", "Application:Services:AzureAISearch:APIKey" : "{azureaisearch-apikey}", "Application:Services:AzureAISearch:Endpoint" : "{azureaisearch-endpoint}", + "Application:Services:APP_ENV": "{app-environment}", "KernelMemory:Services:AzureAIDocIntel:APIKey": "{azureaidocintel-apikey}", "KernelMemory:Services:AzureAIDocIntel:Endpoint": "{azureaidocintel-endpoint}", "KernelMemory:Services:AzureAISearch:APIKey": "{azureaisearch-apikey}", @@ -32,5 +33,6 @@ "KernelMemory:Services:AzureOpenAIText:Deployment": "{azureopenaitext-deployment}", "KernelMemory:Services:AzureOpenAIText:Endpoint": "{azureopenaitext-endpoint}", "KernelMemory:Services:AzureQueues:Account": "{azurequeues-account}", - "KernelMemory:Services:AzureQueues:ConnectionString": "{azurequeues-connection-string}" + "KernelMemory:Services:AzureQueues:ConnectionString": "{azurequeues-connection-string}", + "KernelMemory:Services:APP_ENV": "{app-environment}" } \ No newline at end of file diff --git a/Deployment/resourcedeployment.ps1 b/Deployment/resourcedeployment.ps1 index 02f30dfe..06189ff6 100644 --- a/Deployment/resourcedeployment.ps1 +++ b/Deployment/resourcedeployment.ps1 @@ -600,6 +600,7 @@ try { '{azureaidocintel-apikey}' = $deploymentResult.AzCognitiveServiceKey '{cosmosmongo-chat-history-collection}' = "ChatHistory" '{cosmosmongo-chat-history-database}' = "DPS" + '{app-environment}' = "prod" '{cosmosmongo-document-manager-collection}' = "Documents" '{cosmosmongo-document-manager-database}' = "DPS" '{azureaidocintel-endpoint}' = $deploymentResult.AzCognitiveServiceEndpoint