Configuración de una aplicación en diferentes entornos con Spring Cloud Config

Publicado por pico.dev el , actualizado el .
blog-stack java planeta-codigo programacion
Comentarios

La configuración de una aplicación suele varíar según el entorno en el que se ejecuta, la opción recomendada es que este externalizada y que el artefacto que se despliega en cada entorno sea el mismo. Con Spring Cloud Config en vez de guardar la configuración en un archivo de la propia máquina donde se instala podemos guardar de forma centralizada en un repositorio y que la aplicación obtenga la versión más actualizada cuando se inicia. En este ejemplo explicaré como crear el servidor de configuraciones con Spring Cloud Config y un ejemplo de cliente con Spring Boot que le solicita su configuración según su entorno.

Spring
Java

Desarrollar una aplicación no consiste solo en programar el código que proporciona su funcionalidad, con igual de importancia está como poner en producción esa aplicación para que preste su servicio, algo de lo que el desarrollador no debería ser ajeno. Casi siempre hay algo de configuración que varia entre entornos siendo estos al menos el de desarrollo y producción. En el ciclo de vida de una aplicación esta pasa por varios entornos de ejecución hasta llegar a producción, desde desarrollo, pruebas, QA y finalmente en producción. Casi seguro que la aplicación en cada uno de estos entornos la configuración varía, por ejemplo, las direcciones ya sean IP o nombres de dominio de las bases de datos relacional u otros servicios externos. Para que en el entorno de pruebas y QA se use exactamente el mismo artefacto (en Java un archivo war o jar) que el que se enviaría al entorno de producción la configuración de la aplicación no debería ser incluida en el propio artefacto, si la configuración fuese incluida en el propio artefacto sería distinto que el que se enviaría a producción y las pruebas no válidas, podría haber alguna diferencia en la construcción del artefacto para cada entorno.

El proyecto Spring Cloud con Spring Cloud Config proporciona un mecanismo para externalizar y actualizar de forma sencilla las varias configuraciones de una aplicación en los diferentes entornos en los que se vaya a ejecutar. La opción recomendada es crear un repositorio de Git donde se almacenarán las diferentes configuraciones de la aplicación para cada entorno y bajo un sistema de control de versiones. El que las configuraciones se obtengan de un repositorio y con Git evita que el archivo de configuración esté como un fichero regular en cada máquina del entorno de ejecución, duplicados si hay varias máquinas o con algunas diferencias en cada una. En caso de tener solo una máquina si deja de funcionar o ser accesible perderíamos el archivo de configuración y los cambios que hubiésemos hecho en él directamente, al mismo tiempo estando en un sistema de control de versiones como Git tendremos un histórico de los cambios realizados.

En el caso de este ejemplo usaré la opción del sistema de archivos en vez de Git por ser más sencilla para el ejemplo. Spring Cloud Config usa una arquitectura cliente/servidor en la que cada aplicación al iniciarse solicitará su configuración en función del entorno para el que se desee ejecutar. Spring Cloud Config no solo es usable en aplicaciones Java sino que al proporcionar una API REST y devolver documentos JSON puede ser usado por cualquier lenguaje popular (C#, Python, Ruby, Groovy, …).

Para el ejemplo me basaré en varios artículos que he escrito anteriormente como la herramienta de construcción Gradle ya que con esta herramienta construiré el proyecto, multiproyectos con Gradle dado que el ejemplo se dividirá en dos, la parte cliente y la parte servidor y aplicación autocontenida con Spring Boot como forma de iniciar tanto la aplicación cliente como servidor, también como obtener información y métricas de la aplicación con Spring Boot Actuator. Recomiendo leer estos artículos si no las conoces aún.

Para la parte servidor deberemos incluir como dependencia en el archivo build.gradle la propia del servidor de Spring Cloud Config, org.springframework.cloud:spring-cloud-config-server, y dos archivos de configuración, application.yml y bootstrap.yml donde indicaremos el puerto donde escuchará la aplicación y la ruta del sistema de ficheros del repositorio de configuraciones. En la clase que inicia el servidor con Spring Boot usaremos la anotación @EnableConfigServer.

En el repositorio de configuraciones cada combinación de aplicación y entorno de ejecución tendrá su propio archivo de configuración. En el caso de una aplicación de nombre springcloudclient que se ejecuta en los entornos dev, test y prod los archivos serían los siguientes. Cada archivo tiene similares propiedades de configuración pero posiblemente variando los valores de cada una de ellas. Los archivos pueden definirse en varios formatos, en este caso usando YAML.

En la búsqueda de las ubicaciones de los archivos de configuración se siguen los siguientes patrones, en el caso del ejemplo he usado la segunda opción, el primero que se encuentre es el que se usa:

  • /{application}/{profile}[/{label}]
  • /{application}-{profile}.yml
  • /{label}/{application}-{profile}.yml
  • /{application}-{profile}.properties
  • /{label}/{application}-{profile}.properties

Este sería el inicio del servidor de configuración y el documento JSON que devuelve para la aplicación springcloudclient para el entorno prod en una petición HTTP.

Inicio del servidor Spring Cloud Config
Configuración de la aplicación para el entorno de producción

La aplicación cliente cuando se inicie solicitará su configuración al servidor Spring Cloud Config mediante una petición HTTP en función del entorno para el que se inicie. Deberemos usar la dependencia org.springframework.cloud:spring-cloud-starter-config. Para obtener los valores de las propiedades de configuración podemos usar la anotación @Value. En los archivos application.yml y bootstrap.yml indicamos el perfil para el cual se activará la aplicación y podemos especificar la URL con la localización del servidor de configuración.

Si no queremos obtener las propiedades con la anotación @Value podemos usar el bean Environment que define Spring y sus métodos getProperty con el que además podremos averiguar los perfiles activos de la aplicación. Por otra parte las mismas propiedades de configuración del cliente podemos especificarlos mediante parámetros, propiedades de sistema, propiedades de entorno y algunas formas más como se explica en como externalizar la configuración en las aplicaciones Spring. De cualquiera de estas formas podemos indicar o sobreescribir los valores como puede ser el perfil activo de la aplicación.

Inicio de aplicación cliente de servidor Spring Cloud Config

Este ejemplo solo muestra una pequeña parte de las posibilidades que ofrece Spring Cloud Config, otras son la posibilidad de servir archivos de configuración completos para por ejemplo Nginx, los valores de las propiedades de configuración en el repositorio de configuración pueden ser cifradas y al enviarlas al cliente ser descifradas. Spring Cloud Config solo es una pequeña parte del proyecto Spring Cloud que proporciona más funcionalidades útiles para sistemas distribuidos y microservicios y un complemento adicional interesante para Spring Boot.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando cd server && ./gradlew run && cd .. && client && ./gradlew run.

Yo apoyo al software libre