7

I have a spring boot app that pulls secrets from vault, i want to use these secrets in my application properties file of the spring boot app.

def VAR = new groovy.json.JsonSlurper().parseText(secret)[0].VARKEY
if(VAR != ''){
    echo "Vault Secret pulled Successfully pass is "+VAR
}else{
    echo "Vault Secret Not Found"
}

This code above is successful in setting the variable VAR, how can I then use the VAR to set the value of something in my application properties file in the spring boot application?

Thanks

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
AnonymousAlias
  • 1,149
  • 2
  • 27
  • 68

3 Answers3

5

For reading via application.properties:

Set the value of VAR to the java system or environment and read it in application.properties like

my.app.prop=${ENV_VARIABLE}

For reading in Jenkins file:

In order to read it in jenkins file, write a groovy script and read the property like System.properties[ENV_VARIABLE]

Note: I assuming your Spring boot app and Jenkins runs on the same JVM.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
GAK
  • 1,018
  • 1
  • 14
  • 33
  • Any details on how to set this in the Jenkins file? – AnonymousAlias Nov 18 '19 at 09:04
  • I think the idea he's promoting is that you define the properties in the application.properties file as references to environment variables and then pass the actual values in at runtime ... as environment variables, which in your case, you'd probably set as described here: https://stackoverflow.com/questions/10413936/creating-a-jenkins-environment-variable-using-groovy – Izzy Nov 22 '19 at 04:58
  • @MickO'Gorman I thought your initial question was only for reading it via application.properties file, I have edited my answer for reading it from jenkins file. Hope that make sense. – GAK Nov 22 '19 at 21:26
  • Ok going to accept this answer, the others are correct also but this was first in and you came back to edit. – AnonymousAlias Nov 22 '19 at 23:02
4

You can use spring-cloud-starter-config starter pom dependency to do it in a cleaner and trusted way & avoid Reinventing the Wheel. I have used it a lot and can assure that it works like charm.

Dependency is:

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-vault-config</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>

Usage: You must declare all the properties in application.properties file (Assume these are default values) that you want values mapped from vault.

Then you must declare a spring Configuration annotated with @VaultPropertySource as below:

@Configuration
@Profile("prod")
@VaultPropertySource(
    value = {
      "secret/${spring.application.name}/spring.mail.username",
      "secret/${spring.application.name}/spring.mail.password",
    })
public class VaultConfig {

  @Bean
  @ConditionalOnProperty("spring.cloud.vault.enabled")
  public VaultTemplate vaultTemplate(
      @Value("${spring.cloud.vault.host:localhost}") final String host,
      @Value("${spring.cloud.vault.port:8200}") final String port,
      @Value("${spring.cloud.vault.scheme:https}") final String scheme,
      SessionManager sessionManager) {
    VaultEndpoint vaultEndpoint = VaultEndpoint.create(host, Integer.valueOf(port));
    vaultEndpoint.setScheme(scheme);
    return new VaultTemplateExtension(
        vaultEndpoint, new HttpComponentsClientHttpRequestFactory(), sessionManager);
  }
}

Note:

  1. I have used @Profile annotation just to show how you can configure it for a profile only.

  2. vaultTemplate method receives it's valut server config values either from specified properties or the default values separated by colon.

  3. You can use @ConditionalOnProperty decides when to enable properties to vault secret mapping.

That's all. Now your props have values from vault. You can see how cleanly it populates the values to the properties.

Only one thing to ensure is that you need to specify the properties that receive value from vault in @VaultPropertySource's value property.

Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86
  • hmm not sure whether this will work for me though because in our company we push and pull vault secrets with methods another team has created, so I am able to pull the secrets in my Jenkins file using the other teams method, although I will give it a go tomorrow and see if it works. – AnonymousAlias Nov 19 '19 at 16:24
  • @MickO'Gorman I think you must edit your question and add this comment in the question as question is not that much clear probably. – Vinay Prajapati Nov 23 '19 at 17:25
1

An alternative approach is to use a JAVA Class to read the jenkins var and write to a properties file. Then read it from the properties file. Suppose for example, If USERNAME is one of the String parameters that you use to build the jenkins job, then the same can be accessed in a JAVA Class by using the below code.

System.getProperty("USERNAME");

You can read it directly into the properties file as mentioned by GAK as well. e.g.

${env.JOB_NAME}
Kishore Mohanavelu
  • 439
  • 1
  • 6
  • 17