0

I have a springboot app that uses these versions:

SpringBoot: 2.3.1
SpringCloud: Hoxton.SR5 
SpringData: Neumann-SR1

I've used the custom class as described here (answer from @Arun): Configuring Spring Cloud Vault Config to pull from a location other than /secret

It doesn't even seem to be picking up the vault configs. I have a bootstrap.yml with the following:

spring:
  cloud:
    # Vault configurations
    vault:
      generic:
        enabled: false
      uri: https://${URI}
      authentication: TOKEN
      token: ${VAULT_TOKEN}

    config:
      discovery:
        enabled: true

I'm trying to bring it up locally, so I have my application.yml as follows:

spring:
  datasource:
    url: jdbc:postgresql://localhost:8157/postgres

This is where I'm trying to inject the values from vault into my DataSource:

@Profile(value = {"local", "dev", "stg", "prd"})
@Configuration
public class DatabaseConfig {

  @Autowired
  DatabaseCredentials config;

  @Bean
  @Primary
  public DataSource dataSource() {

    return DataSourceBuilder
        .create()
        .username(config.getUsername())
        .url(config.getUrl())
        .password(config.getPassword())
        .driverClassName("org.postgresql.Driver")
        .build();
  }
}

When the app starts up, it DatabaseCredentials is empty.

The other way I've done it is like this:

public class DatabaseConfig {
  
  @Value("${ccm.database.username}")
  String username;

  @Value("${ccm.database.password}")
  String password;

  @Value("${spring.datasource.url}")
  String url;

  @Bean
  @Primary
  public DataSource dataSource() {
    
    return DataSourceBuilder
        .create()
        .username(username)
        .url(url)
        .password(password)
        .driverClassName("org.postgresql.Driver")
        .build();
  }
}

This has also come up empty saying it can't find a value for ccm.database.username.

What am I doing wrong?

Jobin
  • 5,610
  • 5
  • 38
  • 53
Dany
  • 31
  • 1
  • 5
  • looks like the path for the credentials in vault is missing in your bootstrap.yml – storm_buster Jul 09 '20 at 04:08
  • yea, was trying to use a custom `VaultConfigurer` as defined in the mentioned SO post, instead of defining it in bootstrap. ended up defining a `kv` backend. – Dany Jul 09 '20 at 22:11

3 Answers3

0

You are missing the annotations on DatabaseConfig.java

Which will be something like this.

@Component
@ConfigurationProperties("ccm.database")

So it becomes

@ConfigurationProperties("ccm.database")
@Component
public class DatabaseCredentials {
  
  @Value("${ccm.database.username}")
  String username;

  @Value("${ccm.database.password}")
  String password;

  @Value("${spring.datasource.url}")
  String url;

  // Getters and setters for all properties go here
}

To access the config

@Configuration
public class DatabaseConfig {

  @Autowired
  DatabaseCredentials config;

  @Bean
  @Primary
  public DataSource dataSource() {

    return DataSourceBuilder
        .create()
        .username(config.getUsername())
        .url(config.getUrl())
        .password(config.getPassword())
        .driverClassName("org.postgresql.Driver")
        .build();
  }
}
Jobin
  • 5,610
  • 5
  • 38
  • 53
  • I've tried `@ConfigurationProperties` directly on the `DatabaseConfig.java` class as well as `DatabaseCredentials.java` class, which I then use as shown in my OP above (autowire, then `config.username`). Neither have worked. I get this back as the error: ```2020-07-06 17:25:46,482 DEBUG pool.PoolBase - HikariPool-1 - Failed to create/setup connection: FATAL: password authentication failed for user "username" ``` – Dany Jul 06 '20 at 22:27
  • Thanks for the update, but that's what I had. In fact, the example you provided is what I have in the original Post. But as I said there, when the app starts up, it `DatabaseCredentials` is empty. – Dany Jul 06 '20 at 23:15
  • It is not exactly the same – Jobin Jul 06 '20 at 23:19
  • I have two versions of the `DatabaseConfig.java` class listed above. I'm sorry, other the the `@Profile..` tag, I fail to see what's different in my first version. – Dany Jul 06 '20 at 23:29
0

Spring Cloud Vault gives you DEBUG info which helped me figure out the issue. I ended up defining the path with kv instead of a custom VaultConfigurer bean.

kv:
  enabled: true
  backend: tcds/kv/app-name
  application-name: ccm

This creates the path as follows: tcds/kv/app-name/ccm/${PROFILE}.
I assumed that all secrets underneath this path will be picked up and I originally had multiple folders underneath my path of tcds/kv/app-name/ccm/dev.
For example: ../ccm/dev/database, ../ccm/dev/other-creds.

However, it seems that spring vault wasn't going to the nested paths for secrets and was looking for a file with all credentials there.

So, I removed the dev folder and replaced it with a dev file with entries such as:

{
  "database.username": "blah",
  "database.password": "moreblah",
  "other-creds.user": "dummy"
}

I am able to get credentials from vault by using the DatabaseConfig.java class alone and not having to use DatabaseCredentials.java with the @ConfigurationProperties annotation.

Dany
  • 31
  • 1
  • 5
0

Spring cloud supports import standart spring boot configuration from vault.

use two dependendences for automatic configuration:

  • org.springframework.cloud:spring-cloud-starter-vault-config

  • org.springframework.cloud:spring-cloud-vault-config-databases

See: https://medium.com/digitalfrontiers/manage-your-database-accounts-with-spring-cloud-vault-config-48cecb837a36

Nicolay
  • 7
  • 3