1

Trying to setup a Sprint Boot Application to load configurations from Azure App Configuration, with a reference to a Azure Key Vault entry for properties with sensitive information.

Using App Configuration is working properly and problems emerge when the Key Vault reference is added to App Configuration.

In order to connect to Key Vault, AzureConfigBootstrapConfiguration looks for a KeyVaultCredentialProvider bean, which is not available when it is loaded:

@Bean
    public AzureConfigPropertySourceLocator sourceLocator(AzureCloudConfigProperties properties,
            AppConfigProviderProperties appProperties, ClientStore clients, ApplicationContext context) {
        KeyVaultCredentialProvider keyVaultCredentialProvider = null;
        try {
            keyVaultCredentialProvider = context.getBean(KeyVaultCredentialProvider.class);
        } catch (NoUniqueBeanDefinitionException e) {
            LOGGER.error("Failed to find unique TokenCredentialProvider Bean for authentication.", e);
            if (properties.isFailFast()) {
                throw e;
            }
        } catch (NoSuchBeanDefinitionException e) {
            LOGGER.info("No TokenCredentialProvider found.");
        }
        return new AzureConfigPropertySourceLocator(properties, appProperties, clients, keyVaultCredentialProvider);
    }

Tried to create the bean with highest precedence but it is not working:

@Configuration
public class DemoConfiguration {
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public KeyVaultCredentialProvider keyVaultCredentialProvider() {
        return uri -> new EnvironmentCredentialBuilder().build();
    }
}

Also tried using @Primary and @Priority on bean, and @AutoConfigureBefore(AzureConfigBootstrapConfiguration.class) on DemoConfiguration class, but none of the alternatives work.

Question: Do you know how to create the KeyVaultCredentialProvider bean before AzureConfigBootstrapConfiguration is initialised?

David Campos
  • 1,287
  • 2
  • 13
  • 29
  • Why not simply autowire the KeyVaultCredentialProvider, rather than obtaining it manually? – toolkit Feb 25 '20 at 13:04
  • @toolkit: Getting the bean manually is part of the `AzureConfigBootstrapConfiguration` code, which is provided by the "spring-cloud-azure-appconfiguration-config" dependency. – David Campos Feb 25 '20 at 13:36

3 Answers3

0

It is hard to give any hints without knowing the exact exception and the stack trace that is thrown in your case.

But if it is really a missing configuration at runtime, another way to enforce your own order of configurations is this:

public static void main(String[] args) {
    SpringApplication.run(
       new Class[]{ YourSpringBootApplication.class,
           KeyVaultCredentialProvider.class, 
           AzureConfigBootstrapConfiguration.class // , ...
       }, args);
}

The Class array contains a list of primary sources to load at application startup. So this list does not need to contain all Components and Configurations.

Erunafailaro
  • 1,835
  • 16
  • 21
  • Already tried that without success. While debugging it always goes first to the `sourceLocator` method, not finding the `KeyVaultCredentialProvider` bean that was not initialised yet. Regarding the error code, it is not able to establish connectivity to Azure Key Vault, since the required `KeyVaultCredentialProvider` bean is not provided. – David Campos Feb 25 '20 at 13:38
  • Were you able to confirm that a KeyVaultCredentialProvider Bean is created at all during the application lifetime? – Erunafailaro Feb 25 '20 at 15:36
  • After it is created from `DemoConfiguration`, but then `AzureConfigBootstrapConfiguration` does not have a reference to it and fails to establish connection. – David Campos Feb 25 '20 at 16:18
  • What exception is thrown exactly? NoSuchBeanDefinitionException? Please provide an excerpt of the stack trace. – Erunafailaro Feb 25 '20 at 20:54
  • Thanks for the help. Already found out the solution: https://stackoverflow.com/a/60402852/116803 – David Campos Feb 25 '20 at 21:01
0

Have you set DemoConfiguration in your spring.factories?

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.DemoConfiguration

That should enable it to be found.

mrm9084
  • 430
  • 1
  • 3
  • 12
0

Solution:

Since Azure App Configuration uses BootstrapConfiguration, solution is to create the META-INF/spring.factories file to enable the configuration with the required bean, such as:

org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.davidcampos.autoconfigure.DemoConfiguration
David Campos
  • 1,287
  • 2
  • 13
  • 29