Configuration Management with Consul and WebSocket

Öner Çiller
Trendyol Tech
Published in
4 min readFeb 19, 2020

As Hermes team, we develop logistics and delivery management system for Trendyol. Dashboard, a web application we developed for logistics management, did not have a configuration management on the production environment.

We could have managed simply configs on ConfigMaps since we have been using Kubernetes for container management. However, we didn’t use ConfigMaps because it also brings a variety of disadvantages. For example, when you set any environment variable to ConfigMaps, you have to restart pods to be able to the activate environment variable. (Unless your application handles config changes like capturing events from k8s in application, or pulling ConfigMaps in a schedule)

Therefore, as technology we decided to use Consul and WebSocket, because we wanted to dynamically reflect configurations to the Dashboard.

Configuration Types

We manage two types of configurations:Config and Feature Toggle for the Dashboard.

Config
Config uses for dynamic configurations such as refresh intervals, page counts and API informations.

Feature Toggle
One of the safest ways to deploy new releases on a Trunk Based Development (TBD) is to use Feature Toggle. Therefore we deploy every feature with Feature Toggle, eventually, we can manage it on Consul.

Overview of Consul and architecture

In short, consul is a distributed key-value store. Although consul has a lot of features such as service discovery and service mesh, we only use it for config management. Besides, since consul provides web UI, it makes config management easier when a new environment set or update.

We can ensure that the required services retrieve their configurations from the Consul’s key/value store. The easiest way to do this is to manually add the configuration through Consul’s web UI. Simply by adding a new entry with a key matching the pattern: config/<application_name>/<config_name> you can define a config name with that particular name, for that particular service.

Consul UI

As for the architecture that we built, it is as follows. WebSocket server plays a bridge role in here.

When the consul is updated, the WebSocket server listens for the consul and shares the configs to clients that connected via WebSocket.

WebSocket Server listens for the changes in consul can look like this:

c.client.KV().List() method that is Golang consul library of the Hashicorp that the request will be blocked until the change occurs in other words, long polling will be performed.

Publishing configurations from Consul to Client

In Client side, WebSocket Service which is created to connect to WebSocket Server can look like this:

As you see in code, the client connects to the WebSocket server through the open method and then by using the subscribe method that listens for specific events that come from the server.

For example, in below the client listens for configuration and toggle events using WebSocket Service on the client-side. When the WebSocket server publishes the configurations and toggles, Dashboard will connect through WebSocket Service and it will get all configurations the WebSocket server sent.

When the client retrieve configurations from the server, it will write all configurations to Local Storage through the updateConfig method.

Configurations stored in the browser’s local storage can look like this:

Local Storage

As you see in the following video, we added Feature Toggle v1 and Feature Toggle v2 button to Dashboard. When feature toggle configuration key, FEATURE_TOGGLE_V2_ENABLED, is updated from the consul changes are reflected as realtime.

We use React as the main front-end technology and Redux for state management. Therefore, WebSocket messages are dispatched to redux’s store thus configurations are able to be managed easily like the following code.

renderFeatureToggle = () => {  if (this.props.toggle.isEnabled('FEATURE_TOGGLE_V2_ENABLED')) {
return <Button type={'primary'}>FEATURE TOGGLE V2</Button>;
}

return <Button type={'danger'}>FEATURE TOGGLE V1</Button>;
};

Conclusion

Using Consul and WebSocket, we can manage configurations, by subscribing to changes in that configuration, we are able to change the Configurations and Feature Toggles dynamically in the Dashboard.

--

--