Search code examples
c#azure-functionsazure-app-configuration

how to read azure app config values in C# startup.cs class in azure function


I have added key value pair in Azure app Configuration and trying to read it in Startup.cs class file. Please suggest how to do that.

public class Startup : FunctionsStartup
{
    private static readonly string url= "*******************";
   
    public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
    {
        string connectionString=????? //How to get this value from Azure app config
        builder.Services.AddDbContext<DbContext, Context>(
            options => SqlServerDbContextOptionsExtensions.UseSqlServer(options, connectionString));
       builder.ConfigurationBuilder.AddAzureAppConfiguration(url);
    }
}

Solution

  • You need to split out configuration of your configuration from the registration of your application services. In other words, setup of Azure App Configuration should be done in ConfigureAppConfiguration while the registration of your DbContext should be done from the Configure method. This will allow you to access the Configuration property of the FunctionsHostBuilderContext in the Configure method to retrieve your connection string:

    public class Startup : FunctionsStartup
    {
        private static readonly string url= "*******************";
       
        public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
        {
            // register AzureAppConfiguration only
            builder.ConfigurationBuilder.AddAzureAppConfiguration(url);
        }
    
        public override void Configure(IFunctionsHostBuilder builder)
        {
            var context = build.GetContext();
            var config = context.Configuration;
    
            string connectionString = config["AzureAppConfigKeyName"];
            builder.Services.AddDbContext<DbContext, Context>(
                options => SqlServerDbContextOptionsExtensions.UseSqlServer(options, connectionString)
            );
        }
    }
    

    The value you pass to the indexer of the config object is going to depend on what you named your key in Azure App Configuration. Assuming you called it "DatabaseConnectionString" then that is exactly what you'll pass, ie: config["DatabaseConnectionString"].

    Prefixes

    Azure App Configuration has a few features that can control how the key names are handled by the application, specifically the ability to "Trim Prefixes". You aren't using that here (since you are just passing the URL) but suppose you had keys in Azure App Configuration such as MyFunction:DatabaseConnectionString. By default you would access this using it's full name:

    var cs1 = config["MyFunction:DatabaseConnectionString"];
    // or
    var cs2 = config.GetSection("MyFunction")["DatabaseConnectionString"];
    

    You could however specify the long-form connection options. This would allow you to only select keys that begin with that prefix and optionally trim them off:

    builder.ConfigurationBuilder.AddAzureAppConfiguration(s => 
    {
        s.Connect(url, new DefaultAzureCredential());
        s.Select("MyFunction:*");
        s.TrimKeyPrefix("MyFunction:");
    });
    

    Which would now make your connection string available with a shorter key:

    string connectionString = config["DatabaseConnectionString"];
    

    This feature is especially useful if you have a lot of different settings in your Azure App Configuration instance and only want to pull in those specifically related to your application (labels can also be used for this purpose).

    Azure App Config Connection - Environment Variables

    Finally, a suggestion. Don't store the url or connection details of your Azure App Configuration instance hard-coded in your application. Make use of environment variables for this. "Application Settings" in Azure App Service/Azure Functions are automatically added as environment variables to your application.

    Before ConfigureAppConfiguration has run, a default set of configuration sources has already been added to the context/builder. These include host.json, appsettings.json, local.settings.json (when running locally) and environment variables. A "better" way to configure your link to Azure App Configuration is to use this mechanism.

    For example, you can add a FunctionApp Application Setting named AzureAppConfigUrl that contains this value:

    Application Settings

    Locally you'd add a corresponding entry to your local.settings.json file:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "AzureAppConfigUrl": "https://your-configuration.azconfig.io"
      }
    }
    

    You'd then reference this value when configuring Azure App Configuration. Locally it will pull from the JSON file and when running in Azure it will read from the Application Settings (or rather, the environment variables):

    public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
    {
       var context = build.GetContext();
       var url = context.Configuration["AzureAppConfigUrl"];
       builder.ConfigurationBuilder.AddAzureAppConfiguration(url);
    }