App Configuration References

post

Overview

I recently undertook a backend upgrade to .NET 8 which included a Function App that was relying on App Configuration for the Service Bus Trigger bindings, one thing that I learnt during this upgrade is that the in-process Azure Functions have access to the configuration early enough to allow the Service Bus Triggers to use the config values whereas the dotnet-isolated Functions do not.

Whilst there is a current plan to make the .NET 8 runtime available to the in-process Functions, this is the last version that it will happen, so it feels like it's time to fully adopt the isolated approach to future proof our solutions.

It would be easy enough to either add the configuration values directly to the Function App, this post will provide detail around how to overcome this ServiceBusTrigger issue with App Configuration references to ensure the config remains centralised.

Implementation

There are 2 main sides to getting this working and that is the actual reference and then ensuring managed identity is set up correctly to allow the Function App to read from App Configuration.

Configuration

The following is a Bicep example of adding a reference to a value which includes a label. I've previously covered off a Versioned App Configuration approach and this is a follow on from that.

resource functionAppSettings 'Microsoft.Web/sites/config@2022-03-01' = {
  parent: functionAppResource
  name: 'appsettings'
  properties: {
    AzureWebJobsStorage: '@Microsoft.KeyVault(SecretUri=https://${keyvaultName}${az.environment().suffixes.keyvaultDns}/secrets/AzureWebJobsStorage/)'
    FUNCTIONS_EXTENSION_VERSION: '~4'
    FUNCTIONS_WORKER_RUNTIME: 'dotnet-isolated'
    MyAppConfigurationReference: '@Microsoft.AppConfiguration(Endpoint=https://${appConfigurationName}.azconfig.io; Key=MyAppConfigurationReference; Label=${version})'
  }
}

Managed Identity

The MI approach:

var roleDefinitionAppConfigReaderId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '516239f1-63e1-4d78-a4de-a74fb236a071')

resource appConfigurationResource 'Microsoft.AppConfiguration/configurationStores@2022-05-01' existing = {
  name: appConfigurationName
}

resource roleDefinitionAppConfigurationFunctionApp 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(subscription().subscriptionId, resourceGroup().name, 'something-relevant-to-the-role-assignment')
  scope: appConfigurationResource
  properties: {
      roleDefinitionId: roleDefinitionAppConfigReaderId
      principalId: functionAppResource.identity.principalId
  }
}

The GUID in the variable at the top is actually the role definition ID for the App Configuration Data Reader role, it's an OOTB role and defined so all Azure subscriptions should be able to use it. it's easy to check though within IAM of the App Configuration resource:

IAM

Summary

I am a fan of centralised configuration which is not duplicated across different resources so that's why I use App Configuration, this is just another useful approach that can help with that journey.

Tim Hills

Tim Hills

Tim has been working in solution delivery for over 15 years and has really exceled in the industry. He has been fortunate enough to work with some high-profile clients and challenging projects which has positioned him well for turning business requirements into reality.

Registered office

Address: Arceau Solutions Ltd, Dane John Works, Gordon Rd, Canterbury, CT1 3PP

Telephone: 0208 191 7030