best way for versioning external configuration for microservices? - spring

We are in process of versioning microservice for parallel deployments.
During this process we are versioning the entire service by following git release branches i.e. cut release branches from main during the release and maintain release branches as supporting that specific release.
Now we have a problem we are trying to solve which is Spring Cloud configuration.
We have external config server deployed which gets the configuration from Git repo.
What is best way to version the configuration properties or yaml files?
We have brainstromed different ideas like
single git repo and multiple branches for different version for e.g. service-v1 gets config from v1 branch and service-v2 gets config from v2 branch
single git repo and single branch but use prefix key and suffix as version for e.g. key1.v1=v1, key1.v2=v2
Please let me know what is better/clean approach or any best practices for solving this versioning of of configuration.
Thanks

Related

How I can create a Spring Boot rest api to pull the specific repository branches from GitLab by using GitLab's API?

I want to design a Spring Boot REST API using GitLab's API to pull the specific repository branches from GitLab.
Requirement
We have been working on a big project and that project functionality is getting split into nearly 15 microservices and we have a GitLab repository for each microservice to organise the code remotely. And each repository has many branches like
master branch
dev branch
prod branch
And when we do have a prod release by that time we are raising merge request from dev branch to prod branch by logging into GitLab. And same practice we are doing for all other microservices which need prod deployments. So, here we think rather logging into gitlab and raising merge request from one branch to another branch every time.. we would like to write some Spring Boot service which consumes GitLab services like pulling specific repo details like its branches and other info and then raise merge request from one branch to another branch
So here we mainly looking for two operations one is pull the repository branch details and once pull the branches then raise a merge request from one branch to another branch.
Pull repository branches
Make branch merge request
And we are ready with React UI at client side and looking at REST services with above operations.
As I haven't worked before on such API implementations, I am interested in how achieve the same.
You will want to look into the use of Spring's RestTemplate from the spring-boot-starter-web project. You can use the RestTemplate to call the GitLab APIs to perform your operations on each of the repositories.
Now, there is a lot of information on this subject and a full write-up would be enormous so my suggestion would be to read through Spring's guide on building REST APIs. Baeldung also has a nice little introduction to the rest template that can be found at https://www.baeldung.com/rest-template

Clone only specific path - Spring Cloud Config Server

Is there any way by chance to make spring config server to clone only specific path instead of whole git repo? When I'm running it on production I may not want my entire code base repository to be cloned to some location as it is always a risk. I've done my research and couldn't figure out ways to clone only specific paths of git repo.
One solution is to host the configurations in a seperate repo. But that would defeat the purpose of one code many deploys suggestion of 12factor.net.
Another possibility is to copy the properties into config server's classpath and then to use native profile to load them. But this would defeat the purpose of Spring ConfigServer.
Also kindly do clarify What would be the best way to run spring config server on a production?
You should be separating your code base from your configuration settings.
Repo 1: Your App Code
Repo 2: Your Spring Cloud Config Server Code
Repo 3: Your configuration settings
When you're deploying, you're deploying the code. Not the configuration. A configuration change should not require a new deployment. A new deployment might require an updated configuration change, but the two are generally decoupled.
Configuration can be dynamically updated while code is running. This is completely separate from updating code and deploying the app. That's the whole point of externalized configuration.
TL;DR: You're looking at "one code many deploys" wrong. Configuration is externalized.
I took this straight from 12factor.net
Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires strict separation of config from code. Config varies substantially across deploys, code does not.
Even though you are no longer storing them as constants but still in the same repository is not enough separation from the code. Use a separate repository for configurations.

Git : managing the config files on the master/staging

This may be obvious to some and I have been trying to maintain config files for the spring application. I have spring.xml and springpath.xml so the content is different for each production and dev environment.
When I merge master to my dev branch that merges nicely and then commit the code. Create a pull request for GitHub, at this stage both config files get merged and I end up having dev config files into the master branch too, which is bit annoying.
Is there a better to handle this, please?
thanks
I have solved similar issue by using the Spring Cloud Config, where i have different configuration is maintained for development, staging and production.
All the config are maintained in git (not Github; but definitely not a killer difference). Spring Cloud Config server and config client can help you to get the configuration from git server based on profile that you supply when running the app.
Note:
Since i am using Spring boot, things were really smooth and easy.

spring boot cloud config

I want to use spring cloud config to externalise application properties. I have configured config-server and client, but i don't want to use git(enterprise) as source, this is due to the fact that git may be down for the maintenance. Therefore, i thought about releasing application properties to nexus as application.properties.tar.gz and do the following:
1.) When config-server starts, download the release version from nexus and then unpack the tar.gz to a file system on the server where config-server is running.
2.) The config server which will pick the unpacked properties files.
Please note that the nexus url, application.properties.tar.gz version and location are all passed as VM options to config server.
Is this a sensible option? if this not best option, please could you suggest any other options?
Thanks
kankalam
Unless the Git server is down for maintenance so frequently, I wouldn't go with that option, it seems to be an overkill. Also the Nexus server might go down, so there's no advantage on doing that.
The config server does not read the configuration from the repo once and again, the repository is cloned when configuration is requested. From the docs:
The default strategy for locating property sources is to clone a git
repository (at spring.cloud.config.server.git.uri) and use it to
initialize a mini SpringApplication. The mini-application’s
Environment is used to enumerate property sources and publish them via
a JSON endpoint.
With that in mind, you need to check that the git server you use is available before you start the application or before you refresh its context. If you think it might be a problem, you still have two options:
Set up a dedicated Git server for your application (Check out Gogs as a lightweight option).
Go the "native" way and load the files from the file system. This way you don't have a version control of the configuration files, but you could do it separately into your project.

TeamCity: different branches on different repos on the same build configuration

I have two different VCS roots configured in TeamCity (9.1.4) with master as default and also +:refs/pull/(*)/head in other branch specification.
Now I have a build configuration that uses both repositories.
Building master works just fine but if you try to build a specific pull request/other branch then TC will check the same branch for both repositories.
I know I can add a different VCS with only master and use it for that configuration but is there a way to specify different branches for different repositories on the same build configuration?

Resources