spring-cloud / spring-cloud-vault

Configuration Integration with HashiCorp Vault
http://cloud.spring.io/spring-cloud-vault/
Apache License 2.0
270 stars 151 forks source link

VaultConfigurer not working with latest SpringBoot 3.2.x and Spring Cloud 2023.0.x #720

Closed raj-saxena closed 4 months ago

raj-saxena commented 4 months ago

Describe the bug Context - VaultConfigurer has been working perfectly for us with bootstrap.yml and the deprecated bootstrap way.

We want to migrate to the new ConfigData API but are struggling to correctly configure the SecretBackends with all the other changes happening around migrating BootstrapConfiguration from spring.factories to org.springframework.boot.autoconfigure.AutoConfiguration.imports (from Spring release notes) .

I have spent the last few days going through various Spring docs, old issues in this repo, StackOverFlow and everything that I could find, but can't make it work. The VaultConfigurer is not updating the backend. From the logs -> Screenshot 2024-02-23 at 11 37 18

Key constraint - we don't want to change the default way how the SpringBootApplication is started. So, this suggestion doesn't work for us.

Sample Here's a minimal, reproducible example with just one small commit https://github.com/raj-saxena/vault-configurer/commit/6c3aeef37b102a4ba9da6cf795ebf38ed69f3f87 over Spring Initializer code.

Expectation secret/my-DIFFERENT-application is called instead of the default secret/my-app/dev

A working example can definitely help everyone. Can you tell us what we might be doing wrong?

raj-saxena commented 4 months ago

@mp911de Any suggestions Mark?

mp911de commented 4 months ago

With the ConfigData API, the lifecycle is different. When the configuration is parsed, beans are not yet initialized because the configuration is required to configure the bean container.

Instead, you can register a BootstrapRegistryInitializer.

Check out the documentation on Customize which secret backends to expose as PropertySource and let me know whether that helps or whether you need assistance to connect the dots.

raj-saxena commented 4 months ago

Thanks for the quick reply @mp911de. With your hint, I was able to add the existing VaultConfigurer to the bootstrap process and make some progress towards success with this small change.

However, now I am stuck with another problem. What I am trying to do is that instead of hardcoding, I can use the application name here - https://github.com/raj-saxena/vault-configurer/blob/3570d47a024e802f17a9b360afd04c6048a447eb/src/main/java/com/example/MyVaultSecretConfigurer.java#L11

The BootstrapRegistryInitializer is called too early in the lifecycle and I don't have any properties available. In the past, with bootstrap.yml, I could access properties like spring.application.name, etc and use them for the configuration.

If it is not too much to ask again, can you guide me again, please?

mp911de commented 4 months ago

You have four options:

  1. Instead of using VaultBootstrapper.fromConfigurer, register your own BootstrapRegistryInitializer that registers. I think you should be able to obtain VaultProperties from the InstanceSupplier.context. spring.application.name is read into VaultProperties if spring.cloud.vault.application-name is not set.
  2. Create a new StandardEnvironment to read system properties and Env variables
  3. Read the properties file yourself
  4. Register a ConfigDataLoader and VaultConfigDataLocationResolver yourself to capture the Binder from VaultConfigDataLocationResolver

None is ideal. However, the config data processing is a very early-stage activity.

Let me know whether you require further assistance.

raj-saxena commented 4 months ago

I tried the 1st option and I was able to make it work as per my needs🎉.

I have added a final commit of what I did, along with some cleanup. I'll leave the repo for reference in case it helps someone else.

Thanks a lot for your help again Mark! :)