External Configuration has changed, and we like it.
Let’s be honest, Heroku changed the game. If you’ve ever read or come across the tenets that comprise 12 factor app development, then you can directly thank the engineers over at Heroku.
This post isn’t about all 12 factors though, it’s about only one: Config.
Configuration is a necessary element of any modern software application. The thesis is simple, but the integration of production grade configuration services is anything but.
The twelve-factor app stores config in environment variables (often shortened to env vars or env).https://12factor.net/config
So the first question you should be asking yourself is why environment variables? The answer — they can be changed easily, they don’t necessarily get in the way, and they’re language agnostic (e.g., you can access the same environment variable in python as you can in java). And honestly, they’ve been around forever. Almost everyone with a modicum of technological knowledge has at some point used environment variables, so they’re not some new unknown.
In Java land, especially if you live and breathe Spring Framework or Spring Boot, you’re probably used to putting your configuration files into a Github repository, or some other equivalent VCS, and then layering a few Spring Config Servers in between that and your application runtime (configuration server/s, remember we need high availability!). At Enfuse we’ve done this for years, it’s common practice.
Before the birth of VMware Tanzu a lot of us built applications in PWS (Pivotal Web Services) or PCF (Pivotal Cloud Foundry), both platform offerings from a company called Pivotal. When Pivotal was acquired by VMware, Tanzu appeared on the scene and was built on Kubernetes. The initial fear with a flexible platform like Kubernetes is that any engineer can build anything they want, which in theory is great, but in practice it becomes a polygot nightmare, and results in increased difficulty and expense when attempting to onboard and retain new engineers.
Tanzu brings all the great enterprise elements we had available to us in platforms like PCF, in particular the concepts of cloud native buildpacks. Buildpacks are a fantastic way to optimize the runtime performance of your application, but they also narrow down (or expand) your tech footprint by only allowing certain programming languages to be used when building your software. So if you’re a Java shop, you would just enable the Java buildpack. If you’re a Java shop that has some automation necessary, you could also enable a python buildpack, and so on and so forth.
But before we get too far off track, let’s narrow back into why configuration is so important.
Let’s take a mathematical approach to this problem, and assume the contrary. Let’s assume that configuration is not a necessary element to modern software application development and observe the hypothetical result. Indeed, if configuration was not necessary, then we would have to hard code required configuration values directly into the application. This would mean that we would have separate application code bases for dev, stg, int, uat, and prod. I think we can stop here, this alone would be enough of a nightmare. Any change made would result in a rebuild and redeployment of the application in that respective environment. Then do that four more times, each identically. We haven’t even started talking about secrets yet, or configuration parameters that must be encrypted!
It would be much much more efficient to have only one active code base. Then we extract any dynamic or environment specific values, and we call that configuration. Then we promote one application code base through multiple environments. For example, Application A in Production only uses Application A Production Configuration values. Application B in Dev only uses Application B Dev Configuration values, etc. It sounds obvious, but can get extremely complex.
Spring Config Server traditionally handled this quite nicely. Spring Config Server exposes a REST API that when queried will return properties and values that you then inject into your application and the beginning of runtime to configure necessary Spring Beans. The Spring Config server sits in front of a Github repository where you store your configuration files. Letting the VCS store the configuration files also has fantastic benefits, namely, the versioning of your configuration. What values did your app need last year compared with today? Something weird maybe happening today with my application, what did it’s configuration look like before we updated it yesterday? Well, now you know because you can diff those two commits. Even further, maybe configuration parameters updates every month, but your app only updates every year. This is a great opportunity to transfer ownership of the configuration to a team that employs use of the application rather than the engineers the created the application. Owners of this configuration can easily edit, modify, or rollback to prior configurations while the engineers can keep busy fixing mission critical issues or pivoting to something new.
But this configuration scheme requires that we make a request from a REST API. There could be network issues there. What if you only have one instance of your Config Server? What if that breaks?
VMware, and specifically the folks that created VMware Tanzu Application Configuration Service have taken care of this for us. Instead of the traditional client/server configuration model, the engineers at VMware mount a ConfigMap to the pod the instance is running in. This allows the application to consume the configuration directly from the instances running pod! No more network requests!
Ideally, we would like a flow for application configuration using only one github repository to hold our application source code. Configuration we’d like to keep in individual repositories, however with Tanzu Application Configuration Service it’s not necessary, we could have all of our configuration in one repository if we pleased. For organizational purposes, it’s best practice to ensure the application owner also owns the configuration repository, which makes a monolithic configuration repository and anti-pattern.
In the following diagram we show our desired architecture and with Azure Spring Application Enterprise, and this happens more or less out of the box, very minimal configuration so that we can get up and running quickly!
Perhaps even more importantly, Azure Spring Application Enterprise (ASAE) also employs the use of Tanzu Enterprise Services, namely, Tanzu Application Configuration Service. ASAE is Microsoft and VMware’s joint platform offering, a fantastic runtime that is setup specifically to run all of your mission critical Spring Boot applications. ASAE is so important in fact, that we at Enfuse have created an entire service offering around it called Appshift! and we encourage you to visit the offering below. If you have any questions please contact us at email@example.com.