Application configuration
.NET .NET Core ASP.NET Core Azure Azure App Services C# Visual Studio

How to Configure Web Apps with the Azure App Configuration Service

Welcome to today’s post.

In today’s post I will show how to use the Azure App Configuration service to provide application settings within a .NET Core web application.

The most common approach for using application settings within an application is to store and retrieve application settings within a local file. In a .NET Core environment, the default configuration file used to store application settings is the appSettings.json file.

In previous posts I showed how to use application settings from a local configuration file for application types including console applications, Web API services, Hosted Services, Windows Services, and Azure Functions.

There are going to be requirements with using application settings where we do not want to store some more sensitive settings in a configuration file on the application server. In this case we can use the Azure App Configuration service, which allows us to delegate the storage and retrieval of keys and settings from the cloud and secure the access through using an endpoint with a credential and secret.

The settings keys and values, which would normally be stored in an appSettings.json file, would now be stored within an Azure App Configuration resource as key-value pairs and accessed through an endpoint connection string. This approach is more secure as the keys (credential and secret) can be regenerated to ensure the connection string is refreshed according to recommended security practices.

The Azure App Configuration resource can be found in the Azure Portal by searching for “app configuration”.

In the next section I will show how to create an app configuration resource in Azure.

Creation of an Azure App Configuration resource

The creation of an Azure App Configuration resource requires the specification of resource group, location, pricing tier, and resource name.

After the resource for the Application Configuration service is created, a unique endpoint with the URL format:

https://[resource name].azconfig.io

is created for access to the configuration service.

Managing the access keys for the App Configuration service is through the Access keys menu item under the Settings menu heading.

When opened, you will see the Access keys, which consists of:

  1. An endpoint
  2. A primary key
  3. A secondary key

Each primary and secondary key consists of an Id (credential), a secret, and a Connection String, which is generated from the endpoint, id, and secret.

The connection string is of the format:

Endpoint=https://[app config resource name].azconfig.io;Id=[credential id];Secret=[secret]

To make use of the connection string within our applications, we will need to copy the Connection string from the Access keys from the Portal and paste them into a settings file, a secret manager or into an environment variable on our application server or development environment.

In the next section, I will show how to create and maintain the keys within the app configuration resource.

Creation and Maintenance of Key-Value Pair Settings

To create key-value pairs within the App Configuration service, you will need to open the Configuration explorer menu item, which is accessible from the Operations menu heading as shown:

The initial maintenance page will show no unique keys in the grid section. Creating new key-values I done by clicking on the Create action as shown:

When creating each key-value pair, you have a choice of Key-value or Key Vault reference.

The Key Vault approach further secures the keys and values within a secure Key Vault.

With key-value pairs, you are presented with a dialog that requires entering a unique key, a value, and optional label and content type. Below is the first key I have created:

Below are the keys-value pairs I have subsequently created for the configuration:

KeysValue
BookLoanApp:Settings:LandingPageHeadingWelcome Reader!
BookLoanApp:Settings:LandingPageMessageBrowse through our wonderful collection of Books and Media!

Following creation, the key-value definitions are shown in the grid within the configuration explorer page as shown:

Once we have created the key-value pairs within our Azure App Configuration service, we can then access these settings within a client application hosted either in the Cloud or in an on-premises hosted server environment. 

In the next section, I will show how to access the app configuration settings from within a web application.

Accessing Configuration Settings from an Application

In this section, I will demonstrate the access of settings from an Azure App Configuration service from an ASP.NET Core MVC application.

As I mentioned earlier, we could access the settings from applications of different types. The method I will used can be applied in most .NET Core applications that have a controller (such as an MVC application with or without Razor pages) or have no controller (such as a Web API or minimal Web API).

In all cases, we will access the configuration locally using the built-in JSON configuration provider to extract the connection string, then add the Azure App Configuration service to the service container of our application to access the key-value settings we set up earlier in the Azure Portal.

Before we can do the above, we will need to install two NuGet packages into the project. The first package is the Microsoft.Extensions.Configuration package which allows key-value settings configuration retrieval from an appSettings.json file.

The next package is the Microsoft.Extensions.Configuration.AzureAppConfiguration package which allows key-value settings configuration retrieval from the Azure App Configuration service we created and setup earlier.

In our Startup.cs source file we will first add the uses declarations as shown to make the above packages visible to the Startup class:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.AzureAppConfiguration;

We will also add the following uses declaration to allow our settings to be injected into our controllers:


using Microsoft.Extensions.DependencyInjection;

Below is an excerpt from the appSettings.json configuration file of the AppSettings section and connection string (xxx and yyy are redacted credential and secret values):

"AppSettings": {
    "AppConfigConnection": "Endpoint=https://bookloanwebappconfig12345678.azconfig.io;Id=xxx;Secret=yyy"
}

Obtaining the connection string from the settings file is done with except of code in our ConfigureServices() startup method:

var builder = new ConfigurationBuilder();
string configConnection = Configuration.GetValue<string>(
    "AppSettings:AppConfigConnection"
);

With the configuration connection string we have just obtained from our configuration builder, we add the AddAzureAppConfiguration() middleware to the configuration container, which allows us to connect to the Azure App Configuration service through the connection string, then search for matching keys (my wildcard) to include in the configuration container.

The code excerpt demonstrates this:

builder.AddAzureAppConfiguration(options =>
{
    options.Connect(configConnection)
         .Select("BookLoanApp:*", LabelFilter.Null);
});

The final step is to extract the settings keys-values from the configuration container and bind them into an object of type AppConfiguration. This is shown in the excerpt below:

_configuration = builder.Build();

services.Configure<AppConfiguration>(
    _configuration.GetSection("BookLoanApp:Settings")
);

To be able to set the new keys to a temporary configuration container without overwriting the configuration from the application’s startup configuration container, we make use of a private IConfiguration variable in the Startup class. 

The code showing the configuration properties and ConfigureServices() method is shown below:

public class Startup
{
    private IConfiguration _configuration;

    public Startup(IConfiguration configuration)
    {
      	Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        var builder = new ConfigurationBuilder();
        string configConnection = Configuration.GetValue<string>(
            "AppSettings:AppConfigConnection"
        );

        builder.AddAzureAppConfiguration(options =>
        {
            options.Connect(configConnection)
                .Select("BookLoanApp:*", LabelFilter.Null);
        });

        _configuration = builder.Build();

        services.Configure<AppConfiguration>(
            _configuration.GetSection("BookLoanApp:Settings")
        );

        services.AddControllersWithViews();
        services.AddRazorPages().AddRazorRuntimeCompilation();
}
…

When the application is built and run, with a breakpoint on the _configuration variable, we should see the settings populated within the Data property of the AzureAppConfigurationProvider provider object as shown:

In the next section, I will show how to bind the configuration settings within an application.

Binding Configuration Settings throughout an Application

To allow the configuration settings from the Azure App Configuration service to be accessible throughout the application, we can use the useful options pattern to inject the key-value pairs from the Azure App Configuration service into a model/DTO object. In a previous post I showed how to use the IOptions pattern with application settings within a .NET Core application.

Below is our interface and class for the AppConfiguration object that will store the settings from the configuration service:

namespace BookLoanWebApp.Models
{
    public interface IAppConfiguration
    {
        public string LandingPageHeading { get; set; }
        public string LandingPageMessage { get; set; }
    }
}

namespace BookLoanWebApp.Models
{
    public sealed class AppConfiguration : IAppConfiguration
    {
        public AppConfiguration() { }
        public string LandingPageHeading { get; set; }
        public string LandingPageMessage { get; set; }
    }
}

In the HomeController, we then retrieve the settings from the configuration container. We do this by declaring an IOptions variable as a private member and through the constructor as shown:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly IOptions<AppConfiguration> _appConfiguration;

    public HomeController(ILogger<HomeController> logger, IOptions<AppConfiguration> options)
    {
        _logger = logger;
        _appConfiguration = options;
    }
    …
}

In the Index() controller action we retrieve the settings values as shown:

public IActionResult Index()
{
        IndexModel indexModel = new IndexModel() { 
            HeadingMessage = _appConfiguration.Value.LandingPageHeading, 
            WelcomeMessage = _appConfiguration.Value.LandingPageMessage
        };
        return View(indexModel);
}

The Index page view then maps the settings fields from the AppConfiguration view model into the markup as shown:

@model IndexModel;

@{
    ViewData["Title"] = "Landing Page!!";
}

<div class="text-center">
    <h1 class="display-4">@Model.HeadingMessage</h1>
    <p>@Model.WelcomeMessage</p>
</div>

<br />

<h2 style="color:blue">Main Menu</h2>

<br />

<div>
    @Html.ActionLink("View Books", "List", "Book", null, new { id="viewBookLink" })
</div>

When the application is re-run, the options object passed through the controller constructor shows the values identically retrieved from our cloud configuration service as shown:

And then set within the model for our page view:

The landing page will show the heading message and welcome message display as shown:

From the above we have seen how do implement the following tasks:

  1. Create and configure an Azure App Configuration resource in the Azure Portal.
  2. Setup an application for reading settings from an Azure App Configuration service.
  3. Implement code to read settings using the from an Azure App Configuration provider.
  4. Use retrieved settings within an application.

That is all for today’s post.

In future posts I will expand on the above and show how to implement dynamic retrieval of settings, and how to use labels and features from an Azure App Configuration service.

I hope you have found the above post useful and informative.

Social media & sharing icons powered by UltimatelySocial