Unit 14.00: Configuration that differs by environment
Configuration differs by environment, and none of it belongs in a branch in the code.
Six settings, six differences
Development and production values for each, with the reason.
The code lists them.
CONFIG = {
"app_name": ("classifier", "classifier", "same everywhere"),
"model_name": ("fake-model", "real-model", "fake in dev and CI"),
"log_level": ("DEBUG", "INFO", "quieter in production"),
"reload": ("on", "off", "never on in production"),
"workers": ("1", "4", "shared state must be external"),
"daily_budget_usd": ("0.10", "50.00", "a mistake in dev is cheap"),
}
print(f"{'setting':20} {'development':14} {'production':12} note")
for key, (dev, prod, note) in CONFIG.items():
print(f"{key:20} {dev:14} {prod:12} {note}")
print("""
Every one of these comes from the environment and none from a branch in the
code. `if ENVIRONMENT == "production"` scattered through handlers is how
development behaviour reaches production unnoticed.
The fake model as the development default means a misconfigured environment
fails cheaply rather than expensively.
""")
Every one comes from the environment. if ENVIRONMENT == "production" scattered through handlers is how development behaviour reaches production - the branch is right in every place except the one somebody forgot.
The fake model as the development default means a misconfigured environment fails cheaply rather than expensively.
The mistake this prevents
The mistake is a single config file committed with production values and overridden locally. The production credentials are then in the repository, and a local override that is forgotten reaches production instead.
Takeaway
Every environment difference is a setting read from the environment, not a branch in the code. Default to the safe, cheap value.
