Azure-docs: How to combine MSI and local development?

Created on 19 Dec 2019  Â·  8Comments  Â·  Source: MicrosoftDocs/azure-docs

A sample of how to combine MSI and a local development workflow would be nice


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Pri2 assigned-to-author azure-app-configuratiosvc doc-enhancement triaged

Most helpful comment

I just happened to be setting this up for a project. The method mentioned in this thread ended up working for me: https://github.com/Azure/AppConfiguration/issues/206

var _isLocal = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_HOST_ID"));

var config = new ConfigurationBuilder();

config.AddAzureAppConfiguration(options =>
{
    options.Connect(new Uri(Environment.GetEnvironmentVariable("AppConfigEndpoint")),
        _isLocal ? new DefaultAzureCredential()
                    : (TokenCredential)new ManagedIdentityCredential())
        .ConfigureRefresh(refreshOptions =>
            refreshOptions
                .Register("connections:servicebus")
                            .SetCacheExpiration(TimeSpan.FromSeconds(60))
        );
});

Edit This is for the new version 3 package. The method is a bit different in version 2

One thing to note is that I had to explicitly add my user to the "App Configuration Data Reader Role" even though I have permissions to view the values in the portal.

All 8 comments

@hansmbakker , Thanks for brining this to our attention. We will investigate it further and update you shortly.

@hansmbakker , I'm going to assign this to the document author so they can update the document accordingly.

Thank you!

I just happened to be setting this up for a project. The method mentioned in this thread ended up working for me: https://github.com/Azure/AppConfiguration/issues/206

var _isLocal = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_HOST_ID"));

var config = new ConfigurationBuilder();

config.AddAzureAppConfiguration(options =>
{
    options.Connect(new Uri(Environment.GetEnvironmentVariable("AppConfigEndpoint")),
        _isLocal ? new DefaultAzureCredential()
                    : (TokenCredential)new ManagedIdentityCredential())
        .ConfigureRefresh(refreshOptions =>
            refreshOptions
                .Register("connections:servicebus")
                            .SetCacheExpiration(TimeSpan.FromSeconds(60))
        );
});

Edit This is for the new version 3 package. The method is a bit different in version 2

One thing to note is that I had to explicitly add my user to the "App Configuration Data Reader Role" even though I have permissions to view the values in the portal.

Thank you, @SamaraSoucy-MSFT

I've added an item to our backlog to expand on the use of MSI in a local development environment. I'm going to close this issue for now, but if anyone has further feedback, please don't hesitate to reopen it so we can discuss.

please-close

The best way I've found to combine MSI and local dev is to use the Azure DefaultCredential() class from the azure identity library. From the docs here it reads: "When code is deployed to and running on Azure, DefaultAzureCredential automatically uses the system-assigned ("managed") identity assigned that you can enable for the app within whatever service is hosting it.'" then goes on to read..."When you run your code locally, DefaultAzureCredential automatically uses the service principal described by the environment variables named AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET.'"

There is also a good write up in the Authentication and the Azure SDK docs.

You need to have admin level access on your subscription to give yourself role based access on the app config. In my case i had to give my microsoft account @microsoft.com access to my app config (Access control -> Add -> Add Role assignment-> App configuration data reader)

Once this was setup, my code running in visual studio under my @microsoft.com account worked. Note that the latest lib has nicer shorthand methods than the ones mentioned in this blog
=> options.ConnectWithManagedIdentity(settings["Endpoint"]));

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
var settings = config.Build();
config.AddAzureAppConfiguration(options =>
options.ConnectWithManagedIdentity(settings["Endpoint"]));
})
.UseStartup();

My thoughts:
When doing local development, shouldn't we use local secrets.json? Secret Manager Tool, especially when you're working in a team and you want to use your own test DB connection, etc.
Yes, it's valid to use App Configuration for local development, but not the best practice I think.

This is my solution to use "SMT + MSI" for local/cloud development.
(The user secrets configuration source is automatically added in development mode when the project calls CreateDefaultBuilder)

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
            webBuilder.ConfigureAppConfiguration((hostingContext, config) =>
            {
                if (!hostingContext.HostingEnvironment.IsDevelopment())
                {
                    var settings = config.Build();
                    config.AddAzureAppConfiguration(options =>
                    {
                        options.Connect(new Uri(settings["AppConfig:Endpoint"]),
                            (TokenCredential)new ManagedIdentityCredential());
                    });
                }
            })
            .UseStartup<Startup>());

@jpconnock, @SamaraSoucy-MSFT, please check if my solution is the right way for "SMT+MSI" local/clould development configuration. Btw, the document is still not updated. Do you have a backlog issue to track it?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ianpowell2017 picture ianpowell2017  Â·  3Comments

spottedmahn picture spottedmahn  Â·  3Comments

behnam89 picture behnam89  Â·  3Comments

mrdfuse picture mrdfuse  Â·  3Comments

varma31 picture varma31  Â·  3Comments