1

I have 5 profiles for my Spring Boot application

application.yml
application-prod.yml
application-stg.yml
application-dev.yml
application-local.yml

One default config and 4 for different environments.

application.yml looks like this

spring:
  cloud:
  vault:
    enabled: ${VAULT_ENABLED:false}
    host: ${VAULT_HOST}
    port: ${VAULT_PORT}
    authentication: aws_iam
    aws-iam:
      role: ${VAULT_POLICY}
      server-name: ${VAULT_HOST}
    kv:
      backend: kv
      enabled: true

Some of the properties are provided by the host in the environment variables. To support local development I am overriding authentication in local profile like this

spring:
  cloud:
    vault:
      enabled: true
      authentication: token
      token: ${VAULT_TOKEN}

Now the question is how to import config correctly? If I will do spring.config.import: "vault:" in application.yml it will fail while running with local profile. As ConfigData API will try to resolve vault properties immediately after default profile is processed (but auth info not yet loaded). But as local profile is supposed to use different auth method, it cannot access Vault and fails.

Another question is how to disable Vault in some cases? I could do spring.cloud.vault.enabled=false, but this again would cause failure as ConfigData cannot resolve vault:.

Yes I could use legacy bootstrap mode which would work fine for my scenario, but in the longer run wouldn't be ideal...

Only thing that comes on my mind is to create additional profile, eg vault which would be loaded as a last one. With enabling / disabling this profile I could control if config from Vault is imported or not...

Any other ideas?

siim
  • 366
  • 2
  • 8

1 Answers1

1

We have the same problem, but we have found a workaround overriding the default import order of Spring Boot by importing also the profile-specific configuration files explicitly using spring.config.import in application.yml like this:

spring:
  profiles:
    active: ${STAGE:local}
  config:
    import:
    - optional:classpath:application-${STAGE:local}.yml
    - vault://secret/our-secret

Note that the STAGE environment variable corresponds to the profile used per stage. We made the import of the profile-specific configuration file optional, as we don't have a dedicated file for every stage.

By providing the import for the profile-specific configuration files explicitly before the vault config, we can override the default vault settings before the vault is accessed.

Still, this approach feels a bit awkward, but it's the only way so far we found to work around the issue, so better solutions would be appreciated.

burriad
  • 11
  • 2