There are different ways to manage configuration of a server. A common pattern is to use a combination of multiple sources, such as env variables, config files, cli args etc… and overlapping values are resolved based priority of the source.
eg: configuring a server with a port number.
- cli args (
--port=8080
) - env variable (
port=8080
) - config file (
port: 8080
) - default value (
8080
)
The configuration management system should look up the values and apply the value at the highest priority source.
Config management logic
Example of a config management logic
package main
import (
"fmt"
"os"
"strconv"
)
type Config struct {
Port int
// other fields
}
func LoadConfig() Config {
// default config
config := Config{Port: 8080}
configFromFile := LoadConfigFromFile()
// load from configfile
if configFromFile.Port != 0 {
config.Port = configFromFile.Port
}
// load from env
if os.Getenv("PORT") != "" {
config.Port, _ = strconv.Atoi(os.Getenv("PORT"))
}
// load from cli args
if len(os.Args) > 1 {
config.Port, _ = strconv.Atoi(os.Args[1])
}
return config
}
func main() {
config := LoadConfig()
fmt.Println("Server running on port", config.port)
}
This example shows how a port config is being loaded from different sources and applied based on priority.
External config sources
In larger systems, the configuration is stored in a seperate system like kv store and secret managers. The config management system should be able to fetch the config from these sources and apply the values.
Consul
- Consul is a distributed service mesh to connect, secure, and configure services across any runtime platform and public or private cloud.
- It offers a key-value store to store the configurations.
- It has a built in service discovery and health checks, service mesh to connect the services.
- You can manage values via the UI or the cli.
Vault
- Vault is a tool for securely accessing secrets similar to consul but focused on secret management.
- It offers a key-value store to store the configurations.
- It has a built in secret management system.
- You can manage values via the UI or the cli.
You can have these systems up in your cluster and pull values from them from different services. The config management system should be able to fetch the values from these sources and apply the values.
Config management Patterns
- config file along with the server
- environment variables passed from services like docker-compose, kuberentes etc…
- consul/vault as sidecar to the service, pull and cache during startup / setup refresh.