Configuration without tears
Configuration is the part of a project that nobody plans and everybody suffers from. It starts as a couple of constants at the top of a file and ends as three layers of overrides that no one can fully explain. These are the habits that have kept it manageable for me.
Keep the list short
Every setting is a decision somebody has to make and a way for the system to be wrong. Before adding a new option, ask whether a sensible default would do. Most options I have added over the years were never changed by anyone, including me.
One source of truth for defaults
Defaults should live in the code, in exactly one place, next to the code that uses them. The environment then overrides only what is different. When defaults are scattered across files, a deployment can quietly change behaviour without anyone noticing.
type Config struct {
Port int `env:"PORT" default:"8080"`
DatabaseURL string `env:"DATABASE_URL" required:"true"`
Timeout time.Duration `env:"TIMEOUT" default:"5s"`
}
Fail at startup
A service with a missing or invalid setting should refuse to start and say exactly why. The worst version of this problem is the one that appears three hours after a deploy, when some rarely used code path finally reads the broken value.
Print the effective configuration
When the service starts, log the final configuration, with secrets masked. It turns the question "what is it actually running with?" from an investigation into a glance at the logs.
Keep secrets out of the repository
This one is well known and still violated constantly. Secrets belong in the environment or in a dedicated secret store, and the repository should contain only a template with fake values so that a new developer knows what to provide.
Differences between environments should be small
The more production differs from staging, the less staging tells you. I try to keep the list of differences short enough to fit in a short paragraph, and I write that paragraph down.
Good configuration is invisible. You only notice it when it is missing.