Featured image of post Speed up Azure local development

Speed up Azure local development

A guide on how to speed up local development via a custom TokenCredential factory

Introduction

When developing .NET applications that interact with Azure services, it’s common practice to make use of the Azure.Identity library. This library simplifies the process of authenticating with Azure services by providing a set of credential classes that can be used to obtain access tokens. The simplest and most common way to authenticate is by using the DefaultAzureCredential class, which tries several different credential types in order until one succeeds.

How DefaultAzureCredential works

There are several ways to authenticate with Azure services, such as using a client secret, managed identity, or Azure CLI credentials. DefaultAzureCredential is really awesome as we can generally use the same code to authenticate in different environments 😎

The DefaultAzureCredential tries to cater to all these scenarios by trying the following credential types in order:

DefaultAzureCredential sequence

The problem with this approach is that it can be slow 🦥, especially when running locally. Each credential type has its own way of obtaining an access token, and some of them require network calls or other expensive operations. This can lead to slow startup times for your application, which can be frustrating during development.

Understand your operating environments

It’s important to understand the different environments in which your application will run and how authentication should be handled in each one. For example, you may have different requirements for your production environment compared to your development environment:

Example environment

  • Production - Managed identity
  • Development - Azure CLI

By understanding these differences, you can optimize your authentication strategy for each environment.

Supply options to DefaultAzureCredential

One option to to provide options when creating a DefaultAzureCredential instance. This allows you to specify which credential types should be tried. This can help speed up the authentication process by skipping unnecessary credential types, however the order of the credential types is still the same.

var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
    ExcludeEnvironmentCredential = true,
    ExcludeWorkloadIdentityCredential = true,
    ExcludeManagedIdentityCredential = false,
    ExcludeAzureDeveloperCliCredential = true,
    ExcludeSharedTokenCacheCredential = true,
    ExcludeInteractiveBrowserCredential = true,
    ExcludeAzureCliCredential = false,
    ExcludeVisualStudioCredential = true,
    ExcludeVisualStudioCodeCredential = true,
    ExcludeAzurePowerShellCredential = true,
});

Custom TokenCredential factory

Another option, and my preferred approach, is to create a custom TokenCredential factory that only tries the credential types you need. This can be especially useful when running locally, as you can skip the credential types that are slow or not needed. And it still maintains the benefits of running the same code for different environments.

public static class TokenCredentialFactory
{
    private static readonly TokenCredential[] Sources =
    [
        new AzureCliCredential(),
        new ManagedIdentityCredential()
    ];

    public static TokenCredential Create() => new ChainedTokenCredential(Sources);
}

This factory method creates a ChainedTokenCredential that tries the AzureCliCredential first, and if that fails, falls back to the ManagedIdentityCredential. You can customize this list of credential types to suit your needs.

Conclusion

By understanding the different environments in which your application will run and optimizing your authentication strategy accordingly, you can speed up the authentication and save your precious developer time. Using a custom TokenCredential factory is a great way to achieve this, as it allows you to skip unnecessary credential types and only try the ones you need. This can be especially useful when running locally, where you may not need all the credential types that DefaultAzureCredential tries by default.

comments powered by Disqus
The complete source code for this site can be found on GitHub
Built with Hugo
Theme Stack designed by Jimmy