Designing a Microservice Chassis: Externalized Configuration

A microservice chassis provides two things, build logic and cross-cutting concerns to the services that are built on top of the chassis. In this post we'll look at the externalized configuration.

A microservice chassis provides two things, build logic and cross-cutting concerns to the services that are built on top of the chassis. However, the microservice chassis is not simple to build and needs a lot of consideration. In this post we'll look at the design of an externalized configuration.

Imagine running thousands of microservices and you have to update a configuration value for a few hundred services. You would obviously neither want to change the value for each service by hand nor redeploy the services just because a configuration value changed. This is why we need to externalize and centralize the configuration.

Principles

There a several guiding principles that I consider to be essential for designing an externalized configuration:

  1. Microservices must be able to discover the configuration service location;
  2. Configuration values must be version controlled;
  3. Configuration values must be encrypted in transit and at rest;
  4. Microservices must be notified when a configuration value changes;
  5. A microservice must be able to pull its configuration and, only its configuration, from the configuration service.

Microservices must be able to discover the configuration service location

Consuming services should not care if the configuration service changes location or not. Its location should be discoverable. That said, how will a microservice find the location of the configuration service? We can solve this problem pretty neatly by using DNS SRV records.

Configuration values must be versioned controlled

At any point we should be able to rollback to a previously known good configuration. This requires us to store the history securely and be able to retrieve a diff of the changes between versions. Git will do the trick here - provided that the repository is secured and stored on an encrypted volume.

Configuration values must be encrypted in transit and at rest

Assuming that the configuration service is an HTTP API it can be easily secured using TLS. Securing the configuration at rest can be accomplished in many ways. One is to ensure that the volume on which the configuration data is stored is encrypted. If an HSM is available, we can encrypt the data before storing it and decrypting it when retrieving it.

Microservices must be notified when a configuration value changes

Whenever a configuration value changes a notification must be broadcasted so that the microservices can refresh their internal configurations. This can be broadcasted to only the affected services or to all services. Note that we don't want all the services to refresh their configurations at the same time as this might cause a failure.

A service must be able to pull its configuration and, only its configuration, from the configuration service

For security reasons a service should only be able to access the configuration that belongs to it. There's no reason for one service to have access to another service's configuration. The calling service should ideally present and authentication token to the configuration service.

Conclusion

In this post we looked at how we can create an externalized configuration ensuring security, auditing and discoverability.