Get Azure Configuration value for Blazor - azure

I am trying to pull appsetting.json settings (In Blazor Server app) when I run my code locally and have the settings be pulled from Azure's Configuration when it is running on Azure. But, my code will pull from appsettings.json even if it is live. I pull these values for my Startup.cs file, like this:
options.Authority = Configuration.GetValue<string>("AuthenticationServer:IDAuthority");
options.ClientId = Configuration.GetValue<string>("AuthenticationServer:IDClientID");
options.CallbackPath = Configuration.GetValue<string>("AuthenticationServer:IDRedirectURI");
In my appsetting.json file, I have the settings stored like this:
{
"AuthenticationServer": {
"IDAuthority": "Some Value",
"IDClientID": "Another Value",
"IDRedirectURI": "/Index/"
},
}
And in Azure App Service, under Settings->Configuration, in the Application Settings Tab, I have three key/value pairs:
"IDAuthority" - "New Value"
"IDClientID" - "Another New Value"
"IDRedirectURI" - "/Index/"
But when I do this, the values still get pulled from appsettings.json and not Azure. I've also tried:
"AuthenticationServer_IDAuthority" - "New Value"
"AuthenticationServer_IDClientID" - "Another New Value"
"AuthenticationServer_IDRedirectURI" - "/Index/"
And get the same results. So, how should I pull these values from Azure?
As an aside, getting the Azure db connection string like this, works fine:
services.AddDbContext<DBContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ConnString")));

I think you can only change the code before publish it to AZURE.
Firstly we need to know when we want to read the value stored in azure app configuration, we need to make your application connect to Azure app configuration and then we can get what we set, and we can get value with the key name. And the opreation should be the same as getting value from appsettings.json, here's my code:
var builder = WebApplication.CreateBuilder(args);
ConfigurationManager configuration = builder.Configuration;
var connectionString = "connection_string_of_app_configuration";
builder.Host.ConfigureAppConfiguration(builder =>
{
//Connect to your App Config Store using the connection string
builder.AddAzureAppConfiguration(connectionString);
});
var a = configuration["Logging:LogLevel:Default"];//get log setting in appsetting.json
var c = configuration["Logging:LogLevel:Default"];//also set the same key in azure
var b = configuration["TestApp:Settings:Message"];//get from app configuration
So I think you may comment the code connect to Azure app configuration when you want to read configuration in appsettings.json, and un-comment the code before you want to publish to azure.

Seems to be a naming convention issue. Because my values were nested in my appsettings.json file, I had to make sure the depth of the parameter was included in the Azure setting.
To get the value:
options.Authority = Configuration["AuthenticationServer:IDAuthority"];
and I then had to make sure the configuration setting, in Azure, was titled: "AuthenticationServer:IDAuthority"

Related

Getting a Connection String from Azure App Config via Configuration.GetConnectionString()

Is there a special way to define a Key Value setting for ConnectionStrings in Azure App Configuration?
I have tried using:
ConnectionStrings:DatabaseKeyName
ConnectionStrings\DatabaseKeyName
Using the standard builder.Configuration.GetConnectionString("DatabaseKeyName") always results in a null value. Using builder.Configuration["ConnectionStrings:DatabaseKeyName"] also results in null, however if I use a keyname that does not start with ConnectionStrings (e.g. Test:ConnectionStrings:DatabaseKeyName it works as an app setting via builder.Configuration["Test:ConnectionStrings:DatabaseKeyName"]
The Null value for ConnectionStrings:DatabaseKeyName indicates there is some special handling for ConnectionStrings in Azure App Config, but I don't know where I am going wrong. The Microsoft example pages don't seem to cover ConnectionStrings (except via KeyVault).
Basically I do not want to have to change this:
services.AddDbContext<IciContext>(o =>
{
o.UseSqlServer(Configuration.GetConnectionString("DatabaseKeyName"));
});
To this:
services.AddDbContext<IciContext>(o =>
{
o.UseSqlServer(builder.Configuration["DatabaseKeyName"]);
});
Standard app config connection string setting I need to simulate from Azure App Config:
{
"ConnectionStrings": {
"DatabaseKeyName": "Data Source=localhost;Initial Catalog=xxxx;Integrated Security=True"
},
In my secrets file it is in this format (which does not work with Azure App Config):
{
"ConnectionStrings:DatabaseKeyName": "Server=xxxx;Database=xxxx;User ID=xxxx;Password=xxxx"
}
To get the Connection String from Azure App Configuration, please check the below process.
Install the NuGet Package Microsoft.Azure.AppConfiguration.AspNetCore latest version to add the AddAzureAppConfiguration and read the key values.
To read Azure App Configuration locally, we need to set the secret manager to store the connection string.
dotnet user-secrets init
The above command enables the secret storage and sets the secret ID in .csproj of your application.
In Program.cs, add the below code
var myAppConn= builder.Configuration.GetConnectionString("AppConfig");
Output:
As mentioned in the MSDoc, For the Apps deployed in Azure App Service it is recommended to store Connection String in Configuration Section => Application Settings => Connection Strings of the deployed App.
Is there a special way to define a Key Value setting for ConnectionStrings in Azure App Configuration?
In Azure App Configuration => *YourAppConfiguration* => click on Configuration explorer Under Operations => click on Create => Key-value
In Program.cs, add the below code
var myconn = builder.Configuration.GetConnectionString("AppConfig");
builder.Host.ConfigureAppConfiguration(builder =>
{
builder.AddAzureAppConfiguration(myconn);
})
.ConfigureServices(services =>
{
services.AddControllersWithViews();
});
In any of the cshtml file, add the below code
#using Microsoft.Extensions.Configuration
#inject IConfiguration Configuration
<h1>#Configuration["MyConnection"]</h1>
Output for Key-Value from AppConfiguration:

Azure: Function host is not running

I have a Function App in azure and when I hit the URL of the function app it says "Function host is not running." I have checked the log also in the app insights or in the Azure portal's function app service, it shows the following error message in the function app.
Note: My pipeline's Build & Releases got succeeded, so I am not sure where to check and what is the solution for this. I tried with a new function app but still no luck.
My Startup.cs file to understand How I have referred the config values,
public override void Configure(IFunctionsHostBuilder builder)
{
//var connectionString = Environment.GetEnvironmentVariable("ConnectionStrings:DBConnection");
var serviceProvider = builder.Services.BuildServiceProvider();
_configuration = serviceProvider.GetRequiredService<IConfiguration>();
var appSettingsSection = _configuration.GetSection("AppSettings");
builder.Services.Configure<AppSettings>(appSettingsSection);
var appSettings = appSettingsSection.Get<AppSettings>();
RuntimeConfig.appsettings = appSettings;
var ConnectionString = RuntimeConfig.appsettings.AppDBConnection;
///builder.Services.AddDbContext<ShardingDbContext>(options => options.UseSqlServer(ConnectionString), ServiceLifetime.Transient);
//builder.Services.AddScoped<ITestService, TestService>();
}
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
FunctionsHostBuilderContext context = builder.GetContext();
builder.ConfigurationBuilder
.AddJsonFile(Path.Combine(context.ApplicationRootPath, "local.settings.json"), optional: true, reloadOnChange: false)
.AddJsonFile(Path.Combine(context.ApplicationRootPath, $"{context.EnvironmentName}.settings.json"), optional: true, reloadOnChange: false)
.AddEnvironmentVariables();
}
I am taking the config values as IConfiguration, it works for my local but don't know how to do the same in the server.
while deploying your Function app it neither upload local.settings.json to Azure or nor makes modification on Application Settings based on local.settings.json file.
The Key-value pair related to EIA present in local.settings.json, add the same key-value pair in Azure Function App Configuration > Application Settings in the Portal.
For that we have to manually update the App Settings in portal or if you are using Visual studio, we can update using VS publish panel.
Add Application Settings using Portal
Azure Portal -> Your Azure Function -> Configuration Panel -> Application Settings/Connection Strings (Add your custom configuration)
Add Application Settings using Visual Studio Publish panel
While publishing your azure function Add your Application settings.
In a hosting panel right corner click (...).
Add your app Settings in Manage Azure App Service Settings.
Add your settings like below

How do I allow ContinuousIntegration.exe to use a connection string in Azure Key Vault

I've got a Kentico Xperience (v13) instance in Azure and I want to run ContinuousIntegration.exe to populate my database up there with content from my CI xml files. The catch is that we're injecting the CMSConnectionString setting into the web app from Azure Key Vault (AKV) and the CI.exe isn't seeing it. Instead I get this error message:
CMS.DataEngine.ApplicationInitException: Cannot access the database specified by the 'CMSConnectionString' connection string. Please install the database externally and set a correct connection string.
Or maybe this error message:
Failed to execute the command.
Here's the relevant section from our web.config (that works for the website!):
<connectionStrings>
<!--Should be provided by Azure Key Vault-->
</connectionStrings>
How do I ensure that the executable gets access to the secrets in AKV?
It is possible to let ContinuousIntegration.exe know about a secure connection string with a small custom module that sets the connection string at startup. Here is the basic code of the module:
[assembly: AssemblyDiscoverable]
[assembly: RegisterModule(typeof(AzureConnectionStringModule))]
public class AzureConnectionStringModule : Module
{
public AzureConnectionStringModule()
: base(nameof(AzureConnectionStringModule))
{
}
protected override void OnPreInit()
{
base.OnPreInit();
var azureConnectionString = Environment.GetEnvironmentVariable("SQLAZURECONNSTR_CMSConnectionString");
if (string.IsNullOrWhiteSpace(azureConnectionString))
{
azureConnectionString = Environment.GetEnvironmentVariable("CMSConnectionString");
}
if (!string.IsNullOrWhiteSpace(azureConnectionString))
{
SettingsHelper.ConnectionStrings.SetConnectionString("CMSConnectionString", azureConnectionString);
}
}
}
From a fresh installation of Kentico Xperience 13, here are steps to configure this:
Follow the steps here to add Key Vault support to the admin app locally: https://learn.microsoft.com/en-us/azure/key-vault/general/vs-key-vault-add-connected-service.
Add the module above to the solution in a class library. Make sure the main project references the class library so that it is included during building.
Ensure that the ~\web.config does not have a connection string, or an app setting, named CMSConnectionString.
Deploy the app to an App Service.
In Azure, create an App Service configuration setting with name CMSConnectionString and value #Microsoft.KeyVault(VaultName=your-keyvault;SecretName=CMSConnectionString).
In the Key Vault, create a secret with name CMSConnectionString and value a connection string to an Azure SQL database. You may also need to follow https://learn.microsoft.com/en-us/azure/app-service/app-service-key-vault-references to create an access policy for my App Service.
At this point, the Kentico Xperience 13 admin should load with access to the database.
In the App Service portal, under Development Tools select Console.
In the console, run cd bin and then ContinuousIntegration.exe -r. This should produce a message about the repository not being configured, or output on the restore action.

How to update Azure AppSettings from Azure Webjob by C#?

I have hosted Azure Web Job inside Azure Web Apps which runs every hour and I need to write the Web Job Run time as key value pair. Next time when Webjob run then it will pick the last run time and do its operations. I was thinking of adding Key Value pair in Azure AppSettings of Azure App Service but I am not able to fine any code to update the value in Azure AppSettings.
Can anyone please let me know the code? Please let me know if it is good approach or should I go for Azure Storage Container to store Last Batch Run Time value.
but I am not able to fine any code to update the value in Azure AppSettings.
You could use Microsoft.WindowsAzure.Management.WebSites to achieve it.
var credentials = GetCredentials(/*using certificate*/);
using (var client = new WebSiteManagementClient(credentials))
{
var currentConfig = await client.WebSites.GetConfigurationAsync(webSpaceName,
webSiteName);
var newConfig = new WebSiteUpdateConfigurationParameters
{
ConnectionStrings = null,
DefaultDocuments = null,
HandlerMappings = null,
Metadata = null,
AppSettings = currentConfig.AppSettings
};
newConfig.AppSettings[mySetting] = newValue;
await client.WebSites.UpdateConfigurationAsync(webSpaceName, webSiteName,
newConfig);
}
Or using Azure Fluent Api, refer to this SO thread.

Azure App Service Slot - Environment.GetEnvironmentVariable() returns null

I have just created a "staging" slot in one of my Azure App Services.
In Azure Portal, inside Application Settings for that Slot, I created a new key, as follow:
...and made it a "Slot Setting" as I don't want this value to be swaped.
When I execute my code in a .NET Core project, Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") returns null. Locally it works, as soon as I set this value in my computer environment variables.
Am I missing something?
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") to get the application setting should work on the Azure WebApp. I assume that value is overridden by other codes.
You could debug it with following way.
1.Check the staging kudu(https://yousitename-staging.scm.azurewebsites.net/Env.cshtml) to check environment variable ASPNETCORE_ENVIRONMENT.
2.We also could remote debug slot with VS.
The following is my test steps:
1.Create a .net core project.
2.Create a slot for an existing Webpp and appsetting for slot
3.Check the environment variable with kudu tool
4.Add the following code in the index.chtml.cs file
var appsetting = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
ViewData["appseting"] = appsetting;
5.in the index.chtml file change the title to appsetting value
#page
#model IndexModel
#{
ViewData["Title"] = ViewData["appseting"];
}
6.Publish the WebApp to Azure with debug mode
7.Check the title of the home page.
we also could remote debug to check it.
Not sure where/how you use the Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"), but in my project I retrieve it differently. I retrieve it in the Startup.cs. Could you try something similar and see if you get it this way?
public Startup(IHostingEnvironment env, ILogger<Startup> logger)
{
var envName = env.EnvironmentName;
}
This should give you the env name in the envName variable. If this works I can help you with how you get it other places in your code.

Resources