Saturday, April 22, 2017

Twelve Factor Apps: Spring Cloud Config

I have been using Spring for many years now and I really like the simplicity and non-invasive model of its features. As I have been implementing 12 Factor applications, I needed to start using a central way to configure the many microservices we are building. This is where Spring Cloud Config comes to the rescue.

Spring Cloud Config Architecture

The basic premise is that each application (microservice) can have it's own configuration, but in addition, can receive configuration from a central configuration system - a configuration server. This configuration server is incredibly easy to create with Spring Boot. The following snippets creates the configuration

The following is my example application.yml file that configures my instance of Config Server:

A few things to notice:
  1. By default config server will handle encryption following a pre-determined heuristic. More on that later. Suffice to say that the above configuration is meant to make decryption to happen at the client side instead of the server holding the data.
  2. The key (sample gist shown below) has to be provided for the purposes of ...
  3. The location of the configuration is stored in a git repository. This so happen to be in my local file system, but can be anywhere. One cool aspect of this is that client applications can use a given version, branch or tag of the configuration within this git repo. Version management of configuration is an interesting topic as "highly configurable" software is an interesting concept to implement while preserving the integrity of the application.
  4. The documentation assumes that users of this JVM have installed the Unlimited Strength JCE.

Encryption of Values

While there are many ways to protect your configuration server, a common requirement is about protecting the data (configuration) that is stored on file disk as well as to protect it while in transit. This is pretty common for passwords, hostnames, IPs, etc. Spring Cloud Config offers some options in this space. I recommend asymmetric key encryption for the purposes of protecting the data. The example applications I use on my github repo uses the following script to create the key:

Applications using the above Spring Config Server can use it's properties using the following bootstrap.yml file:

Lessons Learned:

  • I have seen some implementation of "config server" (non Spring solutions) that queries each property remotely. This is dangerous as you can DDOS our own config server on deployment. In Spring Cloud Config, the entire properties file is sent over a single HTTP request.
  • I have been using Spring Cloud release Camden.SR6 (Important). While doing so, I found a bug described here that was causing issues to the decrypting of properties server side.
  • Using defaults is an important strategy. Use it with care.  
  • You can encrypt/decrypt properties using the endpoint (from the server) located at:
    •  localhost:8888/encrypt -d "foo"
  • Properties with the following entry will be decipher as needed:
    • message='{cipher}xxx'
  • Careful between YML and properties files and the {cipher} prefix. As you know, Spring supports property values from "properties" and YML files. Each are supported a bit differently due to the nature of the file (parsers will interpret them differently). This is important to note as the "single" quote may not be needed in one vs the other.

No comments: