Isolated workers - the future of Azure Functions
The Azure Functions team has indicated that net8 will be the last LTS release to receive in-process model support in Azure Functions.
Coupled with the desire to take advantage of the UInt128
support that arrived with .NET 7, I decided it was time to upgrade the functions supporting DevSecTools from .NET 6 in-process to .NET 7 isolated.
Gotchas
Microsoft has a pretty good migration guide that covers what’s going to change in your app, but I ran into a few frustrations along the way.
Testability
Proper testing support for Azure Functions has been a long time coming and is worse in the isolated model due to use of extension methods that make use of internal interfaces which are non-trivial to intercept/mock. Fortunately the Functions Team have enabled support for Castle.DynamicProxy
for those willing to take a gamble on the stability of the library internals.
Azure-side changes
As documented, you’ll need update FUNCTIONS_WORKER_RUNTIME
from dotnet
to dotnet-isolated
.
Be careful of slots! You don’t want an old value for
FUNCTIONS_WORKER_RUNTIME
being dropped in because of a slot-swap
There’s an additional (albeit poorly documented) step involved when moving from net6 to net7 - the linuxFxVersion needs to be set. If you fail to do so your logs will indicate that the appropriate version of the .NET is not installed, for example:
1 | [Error] Failed to start a new language worker for runtime: dotnet-isolated. |
To remedy, update the linuxFxVersion with the az cli:
1 | az functionapp config set --name <FUNCTION_APP> --resource-group <RESOURCE_GROUP> --linux-fx-version "DOTNET-ISOLATED|7.0" |
The linuxFxVersion needs to be updated on all of your slots (there is a --slot
argument supported by the az cli). I also found it necessary to manually restart the function app.
Managed identity flakiness
I unexpectedly saw problems attempting to authenticate via Managed Identity, logs were somewhat vague suggesting some sort of connectivity problem.
1 | Azure.Identity.CredentialUnavailableException: ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint. |
Ultimately I resolved this by disabling and re-enabling managed identity. This generates a new objectId, which requires re-mapping all the appropriate permissions/roles.