This is going to be a slightly weird post in a way as it is going to go round the houses a bit, and not going to contain any actual code, but shall talk about possible techniques of how to best manage specific environment config values for a multi project scala setup
Coming from .NET
So as many of you know I came from .NET, where we have a simple config model. We have App.Config or Web.Config.
We have tools at our disposal such as the XmlTransformation MsBuild tasks which allow us to maintain a set of different App.Config values in them that will be transformed for your different environments
I wrote a post about this here
Here is a small example of what this might look like
So when I started doing multi project Scala projects using SBT where I might have the following project requirements
In the above diagram the following is assumed
- There is a Sacha.Common library that we want to use across multiple projects
- That both Sacaha.Rest.Endpoints and Sacha.Play.FrontEnd are both apps which will need some environment specific configuration in them
- That there is going to be more than 1 environment that we wish to use such as
Now coming from .NET my initial instinct was to put a a bunch of folders in the 2 apps, so taking the Sacha.Rest.Endpoints app as an example we may have something like this
So the idea would be that we would have specific application.conf files for the different environments that we need to target (I am assuming there is some build process which takes care of putting the correct file in place for the correct build within the CI server).
This is very easy to understand, if we want QA we would end up using the QA version of the application.conf file
This is a very common way of thinking about this problem in .NET.
Why Is This Bad?
But hang on here this is only 1 app, what if we had 100 apps that made up our software in total. That means we need to maintain all these separate config files for all the environments in ALL the separate apps.
Wow that doesn’t sound so cool anymore.
A colleague and I were talking about this in some scala code that was being written for a new project, and this is kind of what was being discussed.
I should point out that this idea was not in fact mine, but my colleagues Andy Sprague, which is not something I credited him for in the 1st draft of this post. Which is bad, sorry Andy.
Anyway how about this for another idea. How about the Sacha.Common JAR hold just the specific bits of changing config in separate config files such as
And then the individual apps that already reference the Sacha.Common JAR just include the environment config they need.
This is entirely possible thanks to the way that the Typesafe config library works, where it is designed to include extra config files. These extra config files in this case are just inside of the a JAR that is external -> Sacha.Common
Here is what this might like look for a consumer of the Sacha.Common jar
Where we just include the relevant environment config from Sacha.Common in the application.conf for the current app
And this is what the Sacha.Common may look like, where it provides the separate environment config files that consumers may use
This diagram may help to illustrate this further
Why Is This Cool?
The good thing about this design over the separate config files per environment per application is that we now ONLY need to maintain one set of environment specific settings, which are those in the common Jar Sacha.Common
I wish we could do this within the .NET configuration system.
Hope this helps, I personally think that this is a fairly nice way to manage your configs for multiple applications and multiple environments