Saturday, 29 June 2024

Local Docker Container Run with DefaultAzureCredentials

 We discuss how to enable workload identity for continers running in AKS in the post "Setting Up Azure Workload Identity for Containers in Azure Kubernetes Services (AKS) Using Terraform - Improved Security for Containers in AKS". However, when we use DefaultAzureCredentials and try to run docker containers locally from a development machine, we do not have the workload identity support. With Visual Studio we can run with the Azure AD user and run applications successfully. But if we are using a docker run command and run docker container locally, we will have to use app registration/service principal. Then we have to grant the service principal with required roles in Azure resources we would need to access from the application. Let's take a look at an example with Azure app config.



Consider below code used with default credentials in your application to load configuration from app config service.

using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.AzureAppConfiguration;

namespace common.lib.Configs
{
    public class ConfigLoader
    {
        public static IConfigurationRoot LoadConfiguration(IConfigurationBuilder configBuilder)
        {
            configBuilder.AddJsonFile(Environment.GetEnvironmentVariable("CH_VIDEO_WI_CONFIG-av"));

            var config = configBuilder.Build();


            string? appConfigEndpont = config.GetSection("AppConfigEndpoint").Value;
            string? appConfigLabel = config.GetSection("AppConfigLabel").Value;
            string? sharedAppConfiglabel = config.GetSection("SharedAppConfiglabel").Value;
            string? aadTenantId = config.GetSection("AadTenantId").Value;


            //Load configuration from Azure App Configuration
            configBuilder.AddAzureAppConfiguration(options =>
            {
                DefaultAzureCredential azureCredentials = new();
                options.Connect(
                    new Uri(appConfigEndpont),
                    azureCredentials);

                options
                        .Select(KeyFilter.Any, sharedAppConfiglabel)
                        .Select(KeyFilter.Any, appConfigLabel);

                options.ConfigureKeyVault(opt =>
                    opt.SetCredential(azureCredentials));
            });

            return configBuilder.Build();
        }
    }
}

We can obtain an existing SPN object ID in terraform shown as below.

data "azuread_application" "env_spn" {
  display_name = "my-demo-app-dev"
}

data "azuread_service_principal" "env_spn" {
  client_id = data.azuread_application.env_spn.client_id
}

For app config we can add the "App Configuration Data Reader" role only to dev environment as shown below to the SPN.


Then to run local container you can execute the command as below.

docker run -p 8080:80 -v c:\avconfig:/app/config -e CH_WIDEMO_CONFIG='/app/config/ch-widemo-config.json' -e ASPNETCORE_ENVIRONMENT='Production' -e AZURE_TENANT_ID='tenantid' -e AZURE_CLIENT_ID='spnappid' -e AZURE_CLIENT_SECRET='spnsecret' --name demo-wi-api demo-wi-api:dev

Notice that we are setting  the below env variables correctly in local run for docker container so it can work with SPN authentication.

AZURE_TENANT_ID
AZURE_CLIENT_ID
AZURE_CLIENT_SECRET


No comments:

Popular Posts