Skip to content

alexfalkowski/konfig

Repository files navigation

CircleCI

Konfig

Konfig is a configuration system for application configuration.

Background

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.

Environment Variables

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.

Configuration as Code

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:

Format

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:

Providers

The configuration can be augmented with values that might be sensitive and need to be retrieved at runtime.

Environment Variables

To retrieve an environment variables the value of the key in the config should be env:VARIABLE, ex: env:GITHUB_URL.

Vault

You can store values in vault for safe keeping.

Key

The key format is as follows:

vault:/secret/data/key

An example:

vault:/secret/data/transport/http/user_agent
Value

The value format is as follows:

{"data": { "value": {} }}

An example:

{"data": { "value": "Konfig-server/1.0 http/1.0" }}
Configuration

Environment Variables

SSM

You can store values in ssm for safe keeping.

Key

The key format is as follows:

ssm:/secret/data/key

An example:

ssm:/secret/data/transport/http/user_agent
Value

The value format is as follows:

{"data": { "value": {} }}

An example:

{"data": { "value": "Konfig-server/1.0 http/1.0" }}
Configuration

Environment Variables

Source

This system allows you to store your configuration from various sources. Though we highly recommend that you follow configuration as code.

Git

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

S3 is another way to store your configurations.

To configure we just need the have the following configuration:

Environment Variables

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.

Folder

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.

Server

The server is defined by the following proto contract. So each version of the service will have a new contract.

Dependencies

Dependencies

Client

The client provides a few options.

Config

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 called KONFIG_APP_CONFIG_FILE. This is the default if nothing is passed.
  • file:path - Write to the path.

Secrets

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

Dependencies

Dependencies

Health

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)

Deployment

Since we are advocating building microservices, you would normally use a container orchestration system. Here is what we recommend when using this system:

Other Systems

We love discovering systems that inspire us to make better systems. Below is a list of such systems:

Development

If you would like to contribute, here is how you can get started.

Structure

The project follows the structure in golang-standards/project-layout.

Dependencies

Please make sure that you have the following installed:

Setup

The get yourself setup, please run the following:

make setup

Binaries

To make sure everything compiles for the app, please run the following:

make build-test

Tests

To be able to test things locally you have to setup the environment.

Starting

Please run:

make start

Stopping

Please run:

make stop

Features

To run all the features, please run the following:

make features

Changes

To see what has changed, please have a look at CHANGELOG.md

About

Konfig is a configuration system for application configuration.

Resources

License

Stars

Watchers

Forks

Packages

No packages published