Centralized configuration with Git backing store

Temples surrounding a large building with a statue on top, connected by bridges

Chimera bares its fangs with Viper and Consul

Chimera, my MMORPG server project, is a huge undertaking as a game microservices platform. To succeed, it needs a consistent and reliable method of distributing and watching configuration files across the network. To address this: the servers and microservices now all communicate with a Consul key-value (KV) store for configuration files. The KV store is populated using a Git backing store and then loaded by the services using an open-source library called Viper.

This article covers how Chimera loads configuration files using distributed methods: from files on disk or in Git to settings in memory for each service.



You can learn more about my game microservices project for an MMORPG world in my portfolio.

Standing up the pillars of a game platform

Until now, Chimera hasn’t integrated with other 12-factor app solutions for communication and service management. With this update, the services can all talk to a Consul cluster for a good amount of critical, core features! Consul is a service network solution that will provide Chimera with the following (at the very least):

Key-Value Store

A store of key-value pairs for creating config files and distributed locks.

Secure Network

Ensure cross-service requests are encrypted, authenticated, and authorized.

Service Discovery

A registry of available service endpoints with health updates.

In this article, the key-value store is being used to help distribute configuration files to the rest of the services.

Forging configuration files in a Git backing store

The first step in creating Chimera’s centralized configuration solution is defining how configuration files are stored, organized, and structured. To simplify Chimera and provide configuration files with an audit trail, they’ll be stored in the same git repository as the service code in YAML.

A screenshot of the Git repository storing config files. It shows auth, consul, and forge folders in the root of services/config/service with a common.yml in that root.

In the root of the service config folder, a common.yml file stores common settings for all services. The expectation here is that this common file will later get merged with the service specific configuration YAML file. Other YAML files stored in the service specific folders will also be loaded as separate keys in Consul.

The next step is getting those configuration files from Git to Consul’s KV store. The KV store is what will provide Chimera with a distributed datastore and agents for storing and retrieving configuration details from a centralized location.

Forge will be Chimera’s new microservice for detecting configuration changes and uploading them from Git to Consul. Right now it’s implemented as a docker service using Gonsul, which is a simple tool for importing from Git on a poll.

This tool serves as an entry point for the Hashicorp's Consul KV store.
					  # Gonsul takes Chimera's services git repository and mirrors the config folder into
  # Consul KVs. The goal is to use git as the backing store, audit trail, and access 
  # control mechanism for configuration changes and Consul as the delivery mechanism.
  # https://github.com/miniclip/gonsul
    image: minicliposs/gonsul
      - backend
      - GONSUL_INPUT_EXT=yml
      - GONSUL_KEEP_EXT=true
      - GONSUL_REPO_BASE_PATH=config
      - GONSUL_REPO_ROOT=/chimera/
      - GONSUL_REPO_SSH_KEY=/chimera/service/forge/id_rsa
      - SSH_KNOWN_HOSTS=/chimera/service/forge/known_hosts
      - ./config:/chimera/config/
    command: "gonsul"
        condition: service_healthy

Using the project’s environment variables from .env through Docker Compose, Gonsul can be configured to either load files locally or load them from Git. For local development, I’ve opted for local files; however, the environment variables for publishing will consume changes from git.

Watching for configuration changes from the services

The last step in distributing configuration files to Chimera’s microservices is to set up agents for fetching the latest files and watching for changes. At this point, configuration files are being uploaded to Consul’s KV store as shown below.

A screenshot showing common.yml and the auth service's folder at the root of config in Consul's KV pane.

Each server and service opens a watch (long poll) on the common.yml and service YAML files using an open-source library, this time from HashiCorp directly.

This package provides the api package which provides programmatic access to the full Consul API.

These watches won’t lock the key-values, which allows them to be modified in the background by Forge. Once Forge updates the key-value pair and watches return from their long polls, the configuration file contents will be loaded into Viper. Each file’s Viper instance is then merged in order such that hard-coded settings are overridden by common settings, which are overridden by service settings.

Viper is a complete configuration solution for Go applications including 12-Factor apps. It is designed to work within an application, and can handle all types of configuration needs and formats.

Putting it all together

With Consul now running together with Chimera’s servers and microservices, I’ll soon be able to focus on what the project does rather than the core features of Chimera’s services base. The remaining core features that need done are: centralized logging using Elastic Search, service health and endpoint registration using Consul, gRPC code generation using Protobuf, database generation and migrations, and secret store integration using Vault. Stay tuned!

Share this page


Leave a Reply