AdBlock Detected

It looks like you're using an ad-blocker!

Our team work realy hard to produce quality content on this website and we noticed you have ad-blocking enabled. Advertisements and advertising enable us to continue working and provide high-quality content.

spring cloud config with vault

In a world where microservices-oriented architectures are becoming predominant, where different configurations per environment and adherence to the twelve-factor are necessary, the value of having an externalized configuration increases. Therefore, in this new article on refactoring, we bring an externalized configuration using Spring Cloud Config Server with Vault and Git.

Setting up Spring Cloud Config Server

Spring Cloud Config Server Configuration

The best way to start with Spring Cloud Config is to download the project from the Spring Initializr page. This option will download a project skeleton with all the necessary dependencies.

The downloaded pom.xml will have two dependencies that will be the only ones needed for our configuration:

<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

With the project download, a class whose name ends in Application has been downloaded. This class, located in src/main/java/{package}/*Application, will be the entry point to our service. To use this service as a config server, you will also need to activate it with the annotation @EnableConfigServer.

This class should look as follows:

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigServerApplication.class, args);
	}

}

Once we have the main class, let’s move on to the service’s configuration files.

The downloaded project contains a file named application.properties within the resources folder (src/main/resources). For convenience, let’s rename it to yaml; it can also be called bootstrap.yaml.

In this file, we will configure the application name and leave the default entry port as 8080.

spring:
  application:
    name: config-server


Configuring Spring Cloud Config Server with Git

Spring Cloud Config Server allows us to externalize its configuration through a Git repository. This configuration should be placed in our *.yaml file. Besides the mandatory repository URL, it can include parameters such as the connection username and password.

In our case, we will have the following configuration. For now, we will omit any type of security:

  profiles:
    active: git
  cloud:
    config:
      server:
        git:
          uri: https://github.com/refactorizando-web/spring-cloud-config-server-git

When we access this URL, we can see that we have created a file called application.yaml with one property. We have defined this property as the externalized property, which will be stored in a Git repository instead of being within the application.

Let’s try to start the service and execute the following command:

curl -X “GET” “http://localhost:8080/configclient/default

{
"name":"configclient",
"profiles":[
   "default"
  ],
"label":null,
"version":"6a0691af354e3191e87bf2140c1b731209f1f9a2",
"state":null,
"propertySources":[
{
    "name":"https://github.com/refactorizando-web/spring-cloud-config- 
     server-git/application.yml",
    "source":{
          "properties.hello":"hola",
          "properties.bye":"adios"
       }
    }
  ]
}
{
"name":"configclient",
"profiles":[
"default"
],
"label":null,
"version":"6a0691af354e3191e87bf2140c1b731209f1f9a2",
"state":null,
"propertySources":[
   {
     "name":"https://github.com/refactorizando-web/spring-cloud-config- 
      server-git/application.yml",
     "source":{
         "properties.hello":"hola",
         "properties.bye":"adios"
      }
   }
 ]
}

When executing the previous command, we can see how the properties have been saved in the Git configuration file.

Configuring Spring Cloud Config Server with Vault

What is Vault?

Vault is a HashiCorp platform that allows us to securely store secrets, configurations, passwords, etc. In other words, all sensitive data is in Vault.

Vault follows an encryption process using a master key that is not persisted anywhere. This key is divided into different shards, following the Shamir’s Secret Sharing algorithm.

Deploying Vault with Docker

To use Vault, we need to start it first. We can use a Vault image for that:

docker run -d -p 8200:8200 --name vault -e 'VAULT_DEV_ROOT_TOKEN_ID=myroot' -e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' vault

Once Vault is running, the next step is to enter the Docker container and export the IP and token. The token will be what we defined as myroot.

docker exec -it my-vault /bin/sh #para entrar al contenedor

export VAULT_TOKEN="myroot" export
VAULT_ADDR="http://127.0.0.1:8200"
vault status

After exporting these variables and running vault status, we should see something like this:

Key Value
— —–
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.5.4
Cluster Name vault-cluster-d16ea7ec
Cluster ID 77bab290-f64f-533a-67a8-be56e2acaf85
HA Enabled false

Adding properties to Vault

The next step is to add the properties we want to Vault. We have two methods to do this, through the command line or through its graphical interface:

Adding properties through commands:

If we run the following command without exiting Vault:

vault kv put secret/configclient client.property=hola

In this case, configclient will be the service that connects to the config server to retrieve the property.

Adding properties through the interface:

If we access localhost:8200 from the browser, we will see the Vault interface. We need to provide the token (myroot). In the window that appears, we need to click on “secret” and create a new secret, which will be the name of the service that will be connected to the config server.

Spring Cloud Config Server with Vault and Git
Vault con una propiedad en configclient

Configuring Spring Cloud Config Server with Vault

Once we have saved properties in Vault, it’s time to add the necessary configuration in the bootstrap.yml of the Spring config-server service.

To do this, we will add a new profile called “vault” and add two properties based on the desired execution order. In our case, we have set it to 1, so Vault will be executed before Git. We also see another property “KvVersion: 2”, which is related to the Vault version being used. Without this property, it will not work correctly. The complete yaml will look like this:

spring:
  application:
    name: config-server
  profiles:
    active: vault,git
  cloud:
    config:
      server:
        vault:
          kvVersion: 2
          order: 1
        git:
          uri: https://github.com/refactorizando-web/spring-cloud-config-server-git
          order: 2

If we now start the service and execute the same command as before, we need to add the Vault token to it. So it would be:

curl -X “GET” “http://localhost:8080/configclient/default” -H “X-Config-Token: myroot”

{
"name":"configclient",
"profiles":[
"default"
],
"label":null,
"version":null,
"state":null,
"propertySources":[
  {
     "name":"vault:configclient",
     "source":{
     "client.property":"hola"
  }
},
{
"name":"vault:application",
"source":{
     "baz":"bam",
     "foo":"bar"
    }
 },
 {
   "name":
       "https://github.com/refactorizando-web/spring-cloud-config-server- 
          it/application.yml


.......

We can see the properties created in Vault, and the Git part has been omitted.

Now, we just need to use a Spring Cloud client to see how everything works well. So, let’s do a small example.

Configuring Spring Cloud Client

Configuration of Spring Cloud Service

To connect to a config server and consume the properties, the first step is to add the necessary dependency in our Spring Cloud application:

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>

The next step is to add the endpoint of our config server and the Vault token in our bootstrap.yml file:

spring:
  application:
    name: configclient
  cloud:
    config:
      token: myroot
      uri: http://localhost:8080
server.port: 8888

In the previous file, we have used the same name for the service as we had saved the properties in Vault, and we have changed the port since the default port 8080 is used by the config server.

To conclude, let’s add a controller in the main class that consumes the property from Vault and Git:

@RestController
@SpringBootApplication
public class ClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(ClientApplication.class, args);
	}


	@Value("${properties.hello}")
	private String gitProperty;

	@Value("${client.property}")
	private String vaultProperty;

	@GetMapping("/property")
	public ResponseEntity<String> getProperty() {
		return ResponseEntity.ok(gitProperty + " " + vaultProperty);
	}
}


Conclusion

In this article, we have explored how to externalize our properties using Vault and Git through a Spring Cloud Config Server. The importance of a property externalization system increases when our project consists of multiple services or microservices in different environments. It helps and facilitates the task of managing configurations across different services.

If you want to dive straight into it, you can download the project by clicking here on our GitHub.

Leave a Reply

Your email address will not be published. Required fields are marked *