Using Feature Flags and Externalized configuration .NET Core app with Flagsmith

Problems

The adhering of these two architectural patterns (feature toggles and externalized configuration) helps in three commonly known areas on CI/CD process:

  • configuration of the service and integrations between services become easier due to avoiding re-deployments
  • you can extract your secretes from code base and store them in a separate protected storage

Flagsmith and Alternatives

The majority of tools which I investigated makes focus only on feature flags. It means you can get management and monitoring of Boolean flags, but for configuration settings you’ll need to find another solution. There were such candidates as ConfigCat, LaunchDarkly, featureflag.tech and others which you can find in this list. Most of them offer SaaS solutions, paid and limited only with toggles. In our case we wanted to host on-premise, within boundaries of our intranet. Because of these reasons I stopped on Vault Project in the beginning. It’s very nice from the perspective of security. In contrast its usage appeared not straightforward as it could be. Also UI is not really convenient to use for settings and toggles. And my final choice was for Flagsmith. Both tools are open source, but on top of this, the latter much easier to be deployed in containers. It can be integrated with existing DB clusters, such as Postgres and others, and can be deployed to Docker/Kubernetes easily, it has a lot of client libraries (e.g., for NodeJs, .NET Core) and allows easy access via shell script which is useful for CI/CD pipelines.

Flagsmith features in short

You can use the free plan of their hosted SaaS solution, or deploy an Open Source version to your infrastructure. After deployment you can create organization. For each organization you can create as many environments as you need. You can define flags or settings in any environment and they become available for all environments of the organization.

How we use Flagsmith in our microservices

We use the .NET Core NuGet package of the client library which is version 2.1.3 on the moment of writing this article. We deploy Flagsmith in Docker on our production environment and on local machines of developers.

Wrapping and Abstracting

In their documentation Flagsmith has a simple usage example. The problem with it is that it relies on a singleton class which is not injectable. Because of that we introduced a wrapper class which retains the original usage pattern, but in addition allows injection. We packed it into the internal NuGet package which is used in every microservice where we need the remote configuration. So the interface looks as follows:

User = Microservice

In contrast to the suggested usage of Users in Flagsmith, we use it to identify microservices. We don’t need to have separate configuration per user, but we do need sometimes to override configuration for specific microservice. We might need this during experimenting on the Beta environment, when we need all our services to work as usual, but the service which feeds data into the system needs to stream it from production. There are multiple scenarios to use this feature of Flagsmith.

Migration from appsettings.json

Since Flagsmith allows to store string values, the migration from appsettings files is very simple. Before that we had a huge hierarchy of json-configs because we have four environments and some of our microservices could be run using different configurations on the same environment. We just put JSON text which was in json configs to remote settings. On top of that we introduced user names for different configurations of the same service. The rest has been done by Falgsmith. The service just loads the configuration which it needs. Our appsettings.json files become light and simple.

Naming Convention

In order to not forget the purpose of settings and flags, their origin and usage, we developed a simple convention:

<type>_<scope>_<purpose> (e.g., flag_feederservice_extendedaudit)

Points to Remember

In conclusion I’d like to mention points which seem to be complicated to practice, but at the same time, which are important to follow to make feature flags and externalized configuration work for you and not opposite.

  • Enforce short life span for feature flags and track all of them which need to be removed on your Kanban/Scrum board. Remove them as soon as a feature is fully released
  • Do not use combinations or hierarchy of toggles
  • Use strategy pattern instead of IF and move the toggle point as close to Startup.cs file as possible
  • Inversion of Decision

References

  1. Feature Toggles (aka Feature Flags)
  2. When Feature Flags Go Wrong
  3. Feature Flags: How to Decouple Code from Features
  4. Переключатели функциональности (feature toggles): виды, преимущества и работа с ними в .NET
  5. The Hub for Feature Flag Driven Development

All opinions are my own || Software Developer, learner, perfectionist and entrepreneur-kind person, nonconformist. Always seeks for the order and completeness.