azure-sdk-for-net: KeyVault configuration extension failure

Application uses AzureKeyVaultConfigurationExtensions and runs in a containers with user assigned identity. The identity is granted access to the key vault. On startup, about half the time the application fails when creating the configuration.

From the container logs:

Unhandled exception. Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/6a7b4a78-8f3a-495c-bfc8-db50c01f115b. Exception Message: Tried the following 3 methods to get an access token, but none of them worked.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/6a7b4a78-8f3a-495c-bfc8-db50c01f115b. Exception Message: Tried to get token using Managed Service Identity. Unable to connect to the Managed Service Identity (MSI) endpoint. Please check that you are running on an Azure resource that has MSI setup.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/6a7b4a78-8f3a-495c-bfc8-db50c01f115b. Exception Message: Tried to get token using Visual Studio. Access token could not be acquired. Environment variable LOCALAPPDATA not set.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/6a7b4a78-8f3a-495c-bfc8-db50c01f115b. Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. /bin/bash: az: No such file or directory


   at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.GetAuthResultAsyncImpl(String resource, String authority, CancellationToken cancellationToken)
   at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.<get_KeyVaultTokenCallback>b__8_0(String authority, String resource, String scope)
   at Microsoft.Azure.KeyVault.KeyVaultCredential.PostAuthenticate(HttpResponseMessage response)
   at Microsoft.Azure.KeyVault.KeyVaultCredential.ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Azure.KeyVault.KeyVaultClient.GetSecretsWithHttpMessagesAsync(String vaultBaseUrl, Nullable`1 maxresults, Dictionary`2 customHeaders, CancellationToken cancellationToken)
   at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.GetSecretsAsync(IKeyVaultClient operations, String vaultBaseUrl, Nullable`1 maxresults, CancellationToken cancellationToken)
   at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.LoadAsync()
   at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.Load()
   at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at STCloudAgent.Program.Configure() in /src/STCloudAgent/Program.cs:line 46
   at STCloudAgent.Program.Main() in /src/STCloudAgent/Program.cs:line 55
   at STCloudAgent.Program.<Main>()

Code Snippet

        static void Configure()
        {
            IConfigurationBuilder builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
                .AddEnvironmentVariables();

            var tmpConfig = builder.Build();
            if (tmpConfig.GetValue<bool>("UseAzureKeyVault"))
            {
                var azureServiceTokenProvider = new AzureServiceTokenProvider();
                var keyVaultClient = new KeyVaultClient(
                    new KeyVaultClient.AuthenticationCallback(
                        azureServiceTokenProvider.KeyVaultTokenCallback));

                // identity used by the container must have list & get permissions on the Key Vault
                builder.AddAzureKeyVault(
                    new AzureKeyVaultConfigurationOptions
                    {
                        Vault = $"https://{tmpConfig["KeyVaultName"]}.vault.azure.net/",
                        Client = keyVaultClient,
                        ReloadInterval = TimeSpan.FromMinutes(20),
                        Manager = new DefaultKeyVaultSecretManager()
                    });
            }

            Configuration = builder.Build();
        }

Expected behavior Building the configuration should work reliably

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 19 (10 by maintainers)

Most upvoted comments

Readiness probes also execute repeatedly. The difference is that when a readiness probe fails, the container receives no requests; when a liveness probe fails, the container restarts. I suggested the latter because restarting the container (process) clears static state.