Hey,
We have a quite complex setup of our configuration server. We have one repository per microservice to be able to manage access rights separately for each microservice.
We would like to _share configuration_ to all clients. We used to be able to do this using the native profile (as described here), but with changing to git as configuration storage, we seem to have lost that option.
I have tried using a combination of native and git, but that is not supported.
Next I tried to use the spring.cloud.config.server.git.uri property as a common repo, but that only acts as a fallback if spring.cloud.config.server.git.repos.* are not successfully matching configuration for a specific call to the config server.
My last option seemed using spring.cloud.config.server.git.overrides, which was working great, until I wanted to use variables such as this:
overrides:
eureka.instance.statusPageUrlPath: ${server.contextPath}/info
eureka.instance.healthCheckUrlPath: ${server.contextPath}/health
info.configuration.uri: ${spring.cloud.config.uri}
_Note: There seems to have been a lot of refactors in the org.springframework.cloud.config.server package, so I'm not sure the overrides property is still there._
The config server already fills in the variables before exposing them as json on the REST endpoints.
The result is that all clients receive the following:
"propertySources": [
{
"name": "overrides",
"source": {
"info.configuration.uri": "${spring.cloud.config.uri}",
"eureka.instance.statusPageUrlPath": "/configuration/info",
"eureka.instance.healthCheckUrlPath": "/configuration/health"
}
}
So long story short, we are stuck. Either we continue to use the overrides configuration, and find a solution to passing the variables without being filled in by the config server itself, or we have to find another solution which allows us to share configuration to all clients while using a repository per microservice.
Cheers,
Andreas
Could escaping the placeholders be an option?
It's not really explained in the docs afaik, but seems to be tested here.
When I try it like this:
overrides:
eureka.instance.statusPageUrlPath: $\\{server.contextPath}/info
eureka.instance.healthCheckUrlPath: $\\{server.contextPath}/health
info.configuration.uri: $\\{spring.cloud.config.uri}
The resulting json exposed on the endpoint looks like this:
"propertySources": [
{
"name": "overrides",
"source": {
"info.configuration.uri": "$\\\\{spring.cloud.config.uri}",
"eureka.instance.statusPageUrlPath": "$\\\\{server.contextPath}/info",
"eureka.instance.healthCheckUrlPath": "$\\\\{server.contextPath}/health"
}
}
Is this supposed to be like this?
I don't think you need to escape the "\" in YAML. So $\{server.contextPath}/info would work.
Overrides aren't really a great solution if you want to change the properties locally in the apps. If it works for you for now that's great though.
That did the trick! Thanks!
Overrides are indeed a solution we wouldn't use if there was another way to do this.
Could this be a separate feature?
@andreasevers I think I submitted a similar request at #383...
This is a requirement we need to get done, since we have multiple teams reusing a global configuration that is shared across all teams... But each of them should have control on their own repos...
thanks
Marcello
I'll look into it tomorrow @marcellodesales , stay tuned :)
@andreasevers 👍 Let me know of any development...
@andreasevers Any news❔
Sorry for the radio silence @marcellodesales , had a very busy week.
I love your structured explanation in #383 , and I agree it's overlapping with this issue.
Aside from your remarks I would like to add the "flexible overrides" as an extra requirement.
This would mean the eventual solution would have the following effect on any given application with a profile active:
_1 being top priority and 5 being lowest priority_
I also believe global properties should come from a separate repository. Right now the overrides are defined in the config server itself, which means to change them we need to change the properties, build the config server, release it and deploy it (unless we externalize it but it would be a shame not to use git for this).
It could also a global repository which is always fetched and can be refreshed by POST-ing to the /refresh endpoint of the config-server. A bit like the fallback repository under spring.cloud.config.server.git.uri, but not as a fallback in case the application doesn't have its own repository, but as a global repository that acts as a base for all.
It would be great to have the possibility to define properties that can be overwritten by the application repositories, but also to define properties that will overwrite any property found in application repositories (like the current spring.cloud.config.server.git.overrides does but then inside a git repository). Global properties and global overrides could be in the same repository or in separate repositories. And ideally for these global properties the profiles should also be distinguishable.
@dsyer does that sound reasonable? If so, maybe me and @marcellodesales can work together on a PR.
Some of that makes sense. What I can't get straight in my head (and why I haven't done this myself) is that as soon as you have 2 repositories contributing to the same configuration Environment there's a chance they don't have the same labels. In fact I'd say it is necessary that individual teams can push new labels for their apps without having to change the global defaults. I think it means there is some tricky processing to do in the EnvironmentRepository, and I wouldn't want to do that in the existing repository implementation. The best way to implement it is probably to keep the existing repository and fold it into a composite, which takes the output as it is now and prepends stuff from a default git repository (of which there is only one).
@andreasevers Thanks for your notes as well... So far I'm in need of 2..5, but I can see teams requesting 1.
@dsyer I'm looking in the same angle: global repos would be missing labels, but we could default to master when that happens...
The intent is that this global repo can serve the global properties in all levels:
master in any request to profiles that does not existSince the core team communicates with the capability teams, we can always start with the defaults as usual. The resolution for requests of inexistent labels would resolve in loading the default `master. This could also be an option provided in the bootstrap.yml.
I don't think you want the global repos to not use labels. As an example, say you use labels for environments DEV and PROD and your global configuration is for a common service like RabbitMQ. You'd still want the global config to load the DEV rabbit uri in the DEV environment and the PROD rabbit uri in the PROD environment.
Personally, I'd rather the "global" area of the config be assumed to only hold "application.yml" or "application.properties" files but I don't see why you could also allow application-specific configuration files there. I'd expect the config server to pull the configuration in this order in that case (bottom config wins):
I can see how this could easily be confusing though. I think it's important to spell out exactly what happens when you include a "global" config repository.
Since it would change the behavior in the presence of multiple repositories, I'd propose configuring this look like this:
spring:
cloud:
config:
server:
git:
uri: ssh://git@<falback-git-uri>
globalRepos:
applicationA:
pattern: applicationA/*
uri: ssh://git@<global-git-uri>
applicationB:
pattern: applicationB/*
uri: ssh://git@<global-git-uri>
repos:
applicationName:
pattern: applicationA/*
uri: ssh://git@<applicationA-git-uri>
applicationName:
pattern: applicationB/*
uri: ssh://git@<applicationA-git-uri>
This specific example is a bit non-sensical since you wouldn't want shared configuration to be stored per-application. But you might want to be able to have multiple global configurations on a per-team basis or something like that.
Now I am also facing the same issue to keep global properties should keep in separate repository. Do we have any workaround or solution ?? @andreasevers
Did you try using a composite repository?
Yeah, I tried composite repository but its not working in my case, where both global properties and application properties should use different labels.
If you could create a sample app and post a link that would be super
Does anybody know if there is any solution for this as I have a similar problem.
I have the scenario where a team manages the global-repository level configuration that includes host information, authentication keys etc and they will update this as these properties change. These are common to most services. So basically this repository will contain application.properties.
We then have a service-repository that has the specific service level properties. This contains the {app}.properties files.
Let's say that I have a service named service-a. When the service makes a request for its configuration I need it to return service-a.properties from the service-repository and application.properties from the global-repository. Is this at all possible? Or is the composite repository suggested by @dsyer the only possible solution?
so far just the composite.
Most helpful comment
so far just the composite.