Konfig is a configuration system for application configuration.
Configuration is a very interesting topic. As we build more microservices we need to rethink how we get distributed systems to get their configuration. More info please read External Configuration Store pattern.
Well we have environment variables so why do we need a whole service for this solved problem? That is a great question.
Here are some reasons:
- They are global state.
- The values cannot handle structures more complex than a string.
- They can't be versioned.
- They are hard to verify/validate for correctness.
We want to standardize configuration and check it into version control. We are firm believers of using GitOps. Take a look at Your configs suck? Try a real programming language. Some systems to have a look at:
This system is geared around a very specific system that we use to build services.
The kinds of this config that are supported are:
We recommend that you find a way to validate your configurations. We recommend looking at the following:
The configuration can be augmented with values that might be sensitive and need to be retrieved at runtime.
To retrieve an environment variables the value of the key in the config should be env:VARIABLE
, ex: env:GITHUB_URL
.
You can store values in vault for safe keeping.
The key format is as follows:
vault:/secret/data/key
An example:
vault:/secret/data/transport/http/user_agent
The value format is as follows:
{"data": { "value": {} }}
An example:
{"data": { "value": "Konfig-server/1.0 http/1.0" }}
You can store values in ssm for safe keeping.
The key format is as follows:
ssm:/secret/data/key
An example:
ssm:/secret/data/transport/http/user_agent
The value format is as follows:
{"data": { "value": {} }}
An example:
{"data": { "value": "Konfig-server/1.0 http/1.0" }}
This system allows you to store your configuration from various sources. Though we highly recommend that you follow configuration as code.
Distributed version control is awesome and we believe should be used when managing configuration.
To configure we just need the have the following configuration:
source:
kind: git
git:
owner: the repo owner
repository: the repo name
token: path to token
We expect that the folders to have the following conventions:
application
└── environment
├── continent
│ ├── country
│ │ └── app.kind
│ └── app.kind
└── app.kind
The tag name should be application/version
and kind is yml
.
Some examples:
S3 is another way to store your configurations.
To configure we just need the have the following configuration:
source:
kind: s3
s3:
bucket: The bucket that contains all the configs.
We expect that the folders to have the following conventions:
application
└── version
└── environment
├── continent
│ ├── country
│ │ └── app.kind
│ └── app.kind
└── app.kind
Some examples:
s3://bucket/test/v1.5.0/production/server.kind
s3://bucket/test/v1.5.0/production/eu/server.kind
s3://bucket/test/v1.5.0/production/eu/de/server.kind
Kind is yaml
, toml
.
This is mainly used for testing or if you want to quickly run it. If you have a secure way to mount these configs, then by all means go for it.
To configure we just need the have the following configuration:
source:
kind: folder
folder:
dir: .config (the folder where the configurations can be found)
We expect that the folders to have the following conventions:
application
└── version
└── environment
├── continent
│ ├── country
│ │ └── app.kind
│ └── app.kind
└── app.kind
Kind is yaml
, toml
.
The server is defined by the following proto contract. So each version of the service will have a new contract.
The client provides a few options.
The client can download a configuration.
❯ ./konfig config --help
Get Config.
Usage:
konfig config [flags]
Flags:
-h, --help help for config
-o, --output string output config location (format kind:location) (default "env:KONFIG_APP_CONFIG_FILE")
Global Flags:
-i, --input string input config location (format kind:location) (default "env:KONFIG_CONFIG_FILE")
To configure we just need the have the following configuration:
client:
v1:
host: localhost:8080
timeout: 5s
config:
application: test
version: v1.5.0
environment: staging
continent: '*'
country: '*'
command: server
kind: yml
mode: 0o600
The client writes the config to the location specified by the flag called --output
. As per the following:
env:KONFIG_APP_CONFIG_FILE
- Write to an env variable calledKONFIG_APP_CONFIG_FILE
. This is the default if nothing is passed.file:path
- Write to the path.
The client can write secrets to a specified path.
❯ ./konfig secrets --help
Write secrets.
Usage:
konfig secrets [flags]
Flags:
-h, --help help for secrets
-o, --output string output config location (format kind:location) (default "env:KONFIG_APP_CONFIG_FILE")
Global Flags:
-i, --input string input config location (format kind:location) (default "env:KONFIG_CONFIG_FILE")
To configure we just need the have the following configuration:
client:
v1:
host: localhost:8080
timeout: 5s
secrets:
files:
vault.secret: vault:/secret/data/transport/http/user_agent
ssm.secret: ssm:/secret/data/transport/http/user_agent
path: reports
mode: 0o600
The system defines a way to monitor all of it's dependencies.
To configure we just need the have the following configuration:
health:
duration: 1s (how often to check)
timeout: 1s (when we should timeout the check)
Since we are advocating building microservices, you would normally use a container orchestration system. Here is what we recommend when using this system:
- You could have a global config service or shard these config services per bounded context
- The client should be used as an init container.
We love discovering systems that inspire us to make better systems. Below is a list of such systems:
If you would like to contribute, here is how you can get started.
The project follows the structure in golang-standards/project-layout.
Please make sure that you have the following installed:
- Ruby
- Golang
The get yourself setup, please run the following:
make setup
To make sure everything compiles for the app, please run the following:
make build-test
To be able to test things locally you have to setup the environment.
Please run:
make start
Please run:
make stop
To run all the features, please run the following:
make features
To see what has changed, please have a look at CHANGELOG.md