Search code examples
javaspring-bootarchitecturemicroservicessoftware-design

Updating build dependencies in lots of microservices easily


Using shared libraries in microservices is a bad practice. But every microservice depends on frameworks and libraries: Spring Boot, Kafka Java Client etc.

If a system consists of 30 microservices based on Spring Boot and using Gradle or Maven as a build tool and distributed as Docker images, is there an easy way to update Spring Boot version in all microservices? Updating all microservices one by one takes a lot of efforts. And the more microservices a system has, the more efforts is required.

And the reason for an update may be a security vulnerability in some of dependencies. For example, Spring Boot 2.2.0.RELEASE depends on Tomcat 9.0.27 that has vulnerability CVE-2020-1938 (just as an example). The vulnerability was fixed in Tomcat 9.0.31, so updating to Spring Boot 2.2.4.RELEASE will solve the issue.

A workaround is to declare Spring Boot version in build.gradle as 2.2.+. But someone still has to rebuild all microservices (e.g., on Jenkins).

Also, with this approach you loose control over version management and delegate it to Gradle (always use the latest one version possible). To still have the control over dependencies, versions can be declared in the gradle.properties and mounted into workspace somehow by Jenkins:

spring.version=2.2.4.RELEASE

If the vulnerability is critical there is no time to wait for new Spring Boot version with a fix and Tomcat has to be updated explicitly in the build.gradle. Or even replaced with Undertow what also requires changes in the build.gradle.

Using standalone Tomcat instead of embedded also doesn't help much because microservices are distributed as Docker images and not as WAR files deployed to a servlet container.

In Java EE security updates in theory was super easy. You update an application server (e.g. WildFly) or apply a security patch and if application uses only Java EE API, no further action is required. Is there a similar concept of easy dependencies updates for microservies (at least in theory)?


Solution

  • As a side note, microservices bring value by making components more autonomous and maintainable but that has also a cost : integrate them and maintain them is not cheap. So the microservices granularity should also be considered under that aspect too.

    If a system consists of 30 microservices based on Spring Boot and using Gradle or Maven as a build tool and distributed as Docker images, is there an easy way to update Spring Boot version in all microservices? Updating all microservices one by one takes a lot of efforts. And the more microservices a system has, the more efforts is required.

    With CI tools as Jenkins you quote, relevant automated tests in each microservice application, that is not so hard to update the spring version of their pom/gradle file and even to deploy them in an integration environment with automation IT infrastructure tools as Ansible.
    In a general way, updating the dependency version of all projects may be done with maven/gradle plugin if the projects belong to a multi module project (maven version plugin and gradle version plugin do that).
    If projects don't belong to a multi module project there is also alternative but you should add manual SCM retrievals step.
    The whole task may be done with a shell script or still better with a jenkins job taking as custom job parameter the spring boot version to use and that you can execute on demand. With Jenkins that is still nicer because you can write a pipeline job that integrates both SCM retrieval, docker agent, build execution and also shell execution when needed. And overall you keep all details of executed steps (success as failure) in a tool that your team use.

    In Java EE security updates in theory was super easy. You update an application server (e.g. WildFly) or apply a security patch and if application uses only Java EE API, no further action is required

    From my very recent memories, updating Java EE servers on all environments was never an easy task (not as simple as updating a version in a file).
    Official procedures to update Weblogic and Websphere are very very picky, the updates also take much time because these servers are how to say... bloat, and the rollback to the previous version is not always easy either.