Spring Cloud Config Server con Vault y Git
En un mundo donde actualmente las arquitecturas que predominan comienzan a ser orientadas a microservicios, en el que hay que tener diferentes configuraciones por entorno e intentar cumplir los twelve-factor, aumenta el valor de tener una configuración externalizada. Por ello en este nuevo artículo de refactorizando, traemos una configuración externalizada de mano de Spring Cloud Config Server con Vault y Git.
Configurando Spring Cloud Config Server
Configuración de Spring Cloud Config Server
La mejor manera de comenzar con Spring Cloud Config es descargarse el proyecto desde la página Spring Initializr. Con esta opción se descargará un esqueleto del proyecto con todas las dependencias necesarias.
En el pom.xml que se ha descargado tendremos dos dependencias que serán las únicas que se necesitan para nuestra configuración:
<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>
Con la descarga del proyecto se ha descargado una clase cuyo nombre termina en Application, esta clase que se encuentra en src/main/java/{paquete}/*Application, será el punto de entrada a nuestro servicio. Para poder utilizar este servicio como config server, habrá que además activarlo con la anotación @EnableConfigServer
Esta clase deberá de quedar de la siguiente manera:
@SpringBootApplication @EnableConfigServer public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
Una vez tenemos la clase principal, vamos a ir con los ficheros de configuración del servicio.
El proyecto que se ha descargado, contiene dentro de la carpeta resources (src/main/resources) un fichero con nombre application.properties, por comodidad vamos a renombrarlo a yaml, también se podría llamar bootstrap.yaml.
En este fichero vamos a configurar el nombre de la aplicación y dejaremos como puerto de entrada el de por defecto 8080.
spring: application: name: config-server
Configuración Spring Cloud Config Server con Git
Spring Cloud Config Server, nos va a permitir externalizar su configuración através de un repositorio de git. Esta configuración deberá ir en nuestro fichero *.yaml, aparte de la url del repositorio, la cual es obligatoria, podrá llevar, entre otros parámetros, el usuario y la contraseña de conexión.
En nuestro caso vamos a tener la siguiente configuración, por ahora vamos a omitir cualquier tipo de seguridad:
profiles: active: git cloud: config: server: git: uri: https://github.com/refactorizando-web/spring-cloud-config-server-git
Si accedemos a esta url, podremos ver como lo único que hemos hecho ha sido crear un fichero llamado application.yaml con una propiedad. Esta propiedad que hemos definido será la propiedad externalizada, que en lugar de tenerla en la aplicación estará guardada en un repositorio de git.
Vamos a probar a levantar el servicio y vamos a ejecutar el siguiente comando:
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" } } ] }
Al ejecutar el comando anterior podemos ver como las propiedades han sido guardadas en el fichero de configuración de git.
Configuración Spring Cloud Config Server con Vault
¿Qué es Vault?
Vault es una plataforma de HashiCorp, que nos va a permitir guardar secretos, configuraciones, passwords etc, de manera segura, es decir, todo dato sensible será guardado en vault.
El proceso de encriptado que sigue Vault es realizado con una clave maestra que no es persistido en ningún lado ya que esta clave es dividida en diferentes shards, siguiendo el algoritmo de intercambio secreto de Shamir (Shamir’s Secret Sharing algorithm).
Desplegar Vault con Docker
Para poder utilizar Vault lo primero será arrancarlo, para ello vamos a utilizar una imagen de Vault:
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
Una vez tenemos arrancado Vault, el siguiente paso es entrar en el docker y exportar la IP y el token. El token será lo que hemos definido con myroot.
docker exec -it my-vault /bin/sh
#para entrar al contenedorexport VAULT_TOKEN="myroot" export
VAULT_ADDR="http://127.0.0.1:8200"
vault status
Tras exportar estas variables y ejecutar vault status, deberemos ver algo así:
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
Añadir propiedades a Vault
El siguiente paso será añadir las propiedades que queremos a Vault, para ello tenemos dos métodos, através de línea de comando o través de su interfaz gráfica:
Añadir propiedades a través de comandos:
Si salirnos de dentro de vault ejecutamos lo siguiente:
vault kv put secret/configclient client.property=hola
En este caso configclient, será el servicio que se conectará al config server para obtener la propiedad.
Añadir propiedades a través de la interfaz
Si desde el browser ejecutamos localhost:8200, veremos la interfaz de vault, habrá que añadir el token (myroot). En la ventana que aparece habrá que pulsar secret y crear un nuevo secret, que será el nombre del servicio que se va a conectar al config server para obtener la propiedad. Y una vez creado se podrá añadir la propiedad:
Configurar Spring Cloud Config Server con Vault
Una vez hemos guardado propiedades en Vault toca añadir la configuración necesaria en el bootstrap.yml del servicio config-server de Spring.
Para ello vamos a añadir un nuevo profile que será vault, y le añadiremos dos propiedades en función del orden de ejecución que se quiera, en nuestro caso hemos puesto 1, por lo que ejecutará antes vault que Git. También vemos que tenemos otra propiedad que es KvVersion: 2, esto se debe a la versión de utilización de Vault, sin esa propiedad no funcionará correctamente. El yaml completo quedará de la siguiente manera:
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
Si ahora arrancamos el servicio y ejecutamos el mismo comando que antes habrá que añadirle el token de vault, por lo que sería:
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 .......
Podemos ver las propiedades de vault creadas, la parte de git ha sido omitida.
Ahora tan solo quedaría utilizar un cliente de Spring Cloud para ver como todo funciona bien así que vamos a hacer un pequeño ejemplo.
Configuración de Spring Cloud Client
Configuración del Servicio de Spring Cloud
Para poder conectarnos con un config server, y así poder consumir las propiedades lo primero es añadir la dependencia necesaria en nuestra aplicación de Spring Cloud:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
El siguiente paso será en nuestro fichero bootstrap.yml añadir el endpoint de nuestro config server así como el token de vault:
spring: application: name: configclient cloud: config: token: myroot uri: http://localhost:8080 server.port: 8888
En en fichero anterior hemos puesto el mismo nombre al servicio que como habíamos guardado las propiedades en vault, y hemos cambiado el puerto ya que el puerto por defecto 8080 lo usa el config server.
Y para terminar añadimos un controlador en la clase principal que lo que hace es consumir la propiedad de vault y de 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); } }
Conclusión
En esta Spring Cloud Config Server con Vault y Git, hemos visto como podemos externalizar nuestras propiedades haciendo uso de Vault y de Git, mediante un Config Server. La importancia de un sistema de externalización de propiedades aumenta cuando nuestro proyecto consta de múltiples servicios o microservicios en diferentes entornos, ayudándonos y facilitando el trabajo de tener las configuraciones en diferentes servicios.
Si quieres ir directo puedes descargarte el proyecto pulsando aquí en nuestro github.
Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com o también nos puedes contactar por nuestras redes sociales Facebook o twitter y te ayudaremos encantados!
Otros artículos que te pueden interesar
Entity Graph con JPA en Spring Boot
Orquestación Vs Coreografía en Microservicios
1 pensamiento sobre “Spring Cloud Config Server con Vault y Git”