Azure Linux Containers and App Settings Name/Key 64 character limit

·

5 min read

There is currently a 64 character limit on the App Settings key/names for Azure Service Apps and Azure Functions running a Linux host. This certainly impacts applications that we have that use nested class/options that represent the configuration.

"SomeConfig" : {
    "SomeNestedConfig": {
        "SomeOtherNestedConfig : true
    }
}

The application settings under Configuration would be represented as:

SomeConfig__SomeNestedConfig__SomeOtherNestedConfig

If properties combined surpassed 64 characters, the key/name would be truncated which would cause settings not loading properly.

Currently I'm hitting this issue with these alternatives:

  1. Windows containers or host.
  2. Alter the configuration/settings classes with shorter names and reduce nesting (yuck).
  3. Load up the configurations manually through the Azure SDK through KeyVault if secret or the Service App's Configuration.
  4. Update the dependency configuration extension to check for an existing configuration in the DI container prior to attempting to load the settings.

For option 1, I'd prefer not to do this as the Windows containers are larger in size. This may not matter much if we're just adding a layer that contains our running bits, but the overall image is larger. If we want to run containers via a Service/Web App it seem that Linux is the only current option as error occurs when selecting Windows as the host. Using this options is also not available with the Free or Basic App Plan for the regions I selected. You would be bumped up for a premium plan.

Options 2, also not preferable since the configurations here are relevant for shared dependencies that are imported through nuget packages. Those projects contain the dependency injection extensions that bind the configuration to the settings classes.

For 3, we actually have code for this already, used primarily to load secrets from KeyVault for local development. The authentication is done through a certificate linked to a Service Principal. Loading from the service app's configuration is worth investigating. The only problem issue is authentication. Need to work out the authentication details if we do decide use this option. Do we include the certificate as part of the docker image? If so, we can secure it using a password on load. The password itself would be stored in KeyVault and initial load is done through Azure through the Configuration:

@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)
or
@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret)

This option could be a problem for maintenance.

Option 4 is the most appealing and easy in terms of maintenance. Usually the appsettings configuration is bound to the specific class using:

public static T GetConfig<T>(IConfiguration config, T t, string configName, string baseSection = null)
{
    if (!string.IsNullOrWhiteSpace(baseSection))
    {
        sectionPath = $"{baseSection}:{configName}";
    }

    config.GetSection(sectionPath).Bind(t);

    return t;
}

Where T is some configuration class, let's call it SomeConfig.

In the top layer application we would load appSettings.json or Service App configuration through :

public static IServiceCollection AddSomeConfiguration(
    this IServiceCollection services, IConfiguration config)
{
  var someConfig = new SomeConfig();
  someConfig.SomeSettings1 = config["TopLevel:SomeShorterName"];
  someConfig.SomeOtherSettings = config["TopLevel:SomeOtherShorterKey"];
  services.AddSingleton(someConfig);
}

The downside to this option may have to be building the ServiceProvider from the ServiceCollection. Alternatively, could include an additional extension method that takes in the SomeConfig instance or optional parameter for SomeConfig for the existing method.

I'm surprised this is even an issue...

References: