I don't understand why every document/tutorial I have read on this subject makes it so hard to understand. It's actually pretty straight forward, and it kills me that I've wasted so much of my time stumbling through all of this.
This set of notes will explain how the config server works, how to use it for multiple profile types, and what you need to get it running in your environment.
The config server's entire purpose is to provide a way for other services in your system to get their configuration information. It is a service itself that other services query and it will return back their configuration information at startup and during runtime.
You have 2 main methods for providing this configuration information:
- Reference a github repository
- Reference local files
In my case I went ahead and did the second approach as I didn't want to have to mess with any keys when pulling from the repo. That said, they're both going to do the same thing, this is more to just let you know that both are possible.
The config files themselves are the same type of .yml
config files that you're used to created on the service itself. Rather than putting all of the application specific information within the application's config files, the idea is to take all of that data out and move it to a file that the config server will serve up. Instead, the only thing in your local file will be information telling the application how to contact the config server.
This means that your service will essentially be a config client. This is an important thing to remember when you're using spring initializer to generate your packages... You need it.
Typically on the actual service you're used to creating an application.yml
file. Maybe you're also used to having things like application-env.yml
files for specific environment profiles. This same thing carries over to the config server.
The application specific config files will be constructed as follows: {spring.application.name}-{spring.profiles.active}.yml
. Note that the profile portion is optional, and that BOTH can actually be used.
Lets assume that my service/application is called discover-service
. I could create the following application specific config files:
discovery-service.yml
discovery-service-dev.yml
discovery-service-test.yml
discovery-service-prod.yml
When this service goes to poll the config for its config data, it's possible that it will pull back up to two of these configs. If no profile is provided on startup, it will only access the base discovery-service.yml
file.
However, if we were to start the service with a specific profile parameter (let's say prod
), It will take both discovery-service.yml
as well as discovery-service-prod.yml
, where the prod
file will take precedence over the other.
To extend this even further, it's also possible to configure generic profile configurations, say for your dev
or prod
services that you want applied to all of the services. This might be general security configuration that you want to be applied to everything, rathe than having to duplicate it across multiple files.
This is done by creating application-{profile}.yml
config files. This additional profile information will be pulled in when the config is loaded. The order of precedence seems to be the following:
{service.name}-{profile}.yml
application-{profile}.yml
{service.name}.yml
- service's
application.yml
In other words, if the value exists in all of these, the one in the top will be the one that's finally used.
- Your client application will be configured with a base
bootstrap.yml
file that will tell the service where the config server is located:
spring:
application:
name: discovery-service
cloud:
config:
uri: http://localhost:8088
- Configure config file for both
discovery-service.yml
anddiscovery-service-dev.yml
where the server.port is different in both of them. - Service is started with an extra parameter passed from the command line to set the active profiles (
--spring.profiles.active=dev
). - The service should start up using the port that was specific in the
-dev.yml
file - Kill the service and restart using a profile for which a config doesn't exist
- The service should start up using the port that's defined back in the
discovery-service.yml
file.
I using spring initializer for all of my projects, so I'll just assume it's a common thing that others do. When doing so, you need to ensure you grab the following packages, depending on whether you're making a config server or a config client:
- Config Server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
- Config Client
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>