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.
Chimera
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.
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.
miniclip/gonsul
# 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
forge:
image: minicliposs/gonsul
networks:
- backend
environment:
- GONSUL_ALLOW_DELETES=true
- GONSUL_CONSUL_URL
- GONSUL_CONSUL_BASE_PATH
- GONSUL_INPUT_EXT=yml
- GONSUL_KEEP_EXT=true
- GONSUL_LOG_LEVEL
- GONSUL_POLL_INTERVAL
- GONSUL_REPO_BRANCH=main
- GONSUL_REPO_BASE_PATH=config
- GONSUL_REPO_ROOT=/chimera/
- GONSUL_REPO_URL
- GONSUL_REPO_SSH_KEY=/chimera/service/forge/id_rsa
- GONSUL_REPO_SSH_USER=git
- GONSUL_STRATEGY=POLL
- SSH_KNOWN_HOSTS=/chimera/service/forge/known_hosts
volumes:
- ./config:/chimera/config/
command: "gonsul"
depends_on:
consul-client:
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.
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.
hashicorp/consul
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.
spf13/viper
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!