Production-Grade Configuration Management β€” Lecture Notes


1. What is Configuration Management?

Definition: The systematic approach to organizing, storing, accessing, and maintaining all the settings of a backend application.

Think of it as the DNA of your application β€” it decides how your code behaves in different environments without changing the code itself.

Common misconception: Config management = just database passwords and API keys.

Reality: It covers a much broader scope:

  • How the application starts up
  • How it connects to external services
  • What it logs, at what level, and where
  • Which features are enabled or disabled
  • For which users which features are active
  • Performance tuning parameters
  • Business rules and security settings

2. Types of Configuration

2.1 Application Settings

The most common type β€” controls core behavior of the running app.

SettingExample
PORTWhich port the server runs on (local: 8080, production: may differ)
LOG_LEVELdebug in development, info in production
REQUEST_TIMEOUTHow long before a request is dropped (e.g., 60s β†’ AI image gen taking 80s β†’ 504)
DB_POOL_SIZEMax open DB connections (10 locally, 50 in production)

2.2 Database Config

All parameters needed to connect to the database:

host, port, username, password, database_name
β†’ combined into a connection URL

Plus: query timeout (how long before a DB query is aborted).


2.3 External Service Config

API keys and connection details for every third-party integration:

  • Email providers (Resend, Mailchimp) β†’ API key
  • Payment processors (Stripe) β†’ secret key
  • Auth providers (Clerk, Auth0) β†’ API key
  • Cloud storage (S3) β†’ access key + secret

2.4 Feature Flags

Dynamically enable or disable features without deploying new code.

Use cases:

  • A/B testing a new checkout flow for a subset of users
  • Rolling out a feature region-by-region (enable for US, disable for India)
  • Disabling a broken feature instantly in production without a deployment

Feature flags add a config layer that sits above code β€” the same codebase can behave differently for different users or environments.


2.5 Other Config Types

TypeExamples
Security configJWT secret, session secret, token expiry
Infra / DevOps configKubernetes settings, deployment parameters
Performance tuningMax CPUs (Go GOMAXPROCS), thread pool sizes
Business rulesMax order quantity per user, discount limits

3. Config Characteristics

Not all configs are equal. Classify them before storing:

CharacteristicExamples
Sensitive / secretDB password, API keys, JWT secret β†’ must be encrypted
Non-sensitivePort number, log level, pool size β†’ can be in plain files
Environment-specificDB URL (localhost in dev, cloud in prod)
Shared across environmentsMax string length rules, timeout values
Frequently changingFeature flags
Rarely changingConnection pool size, port

4. Configuration Storage Options

4.1 Environment Variables

Most common. Loaded from .env file (locally) or injected by the deployment platform (production).

Local: .env file + a library like dotenv loads values into process.env (Node.js) or os.Getenv (Go).

Production flow:

Deployment triggers
      ↓
Fetch secrets from cloud provider (Vault, AWS Parameter Store, etc.)
      ↓
Inject as environment variables into the container / process
      ↓
App starts β†’ reads from environment

4.2 Config Files (YAML / TOML / JSON)

Used heavily in open-source projects. YAML is preferred over JSON because it supports comments.

Example (config.yaml):

server:
  port: 8080
  log_level: debug  # change to "info" in production

database:
  host: localhost
  pool_size: 10

features:
  new_checkout: false

TOML is a newer alternative β€” also supports comments, cleaner syntax for nested configs.


4.3 Dedicated Secrets Management Services

For production systems with distributed deployments:

ServiceProvider
HashiCorp VaultOpen source + cloud
AWS Parameter Store / Secrets ManagerAWS
Azure Key VaultAzure
Google Secret ManagerGCP

What these provide:

  • Secrets encrypted at rest and in transit
  • Access control (who can read which secret)
  • Audit logs (who accessed what and when)
  • Automatic secret rotation
  • Integration with Kubernetes, CI/CD pipelines

4.4 Hybrid Strategy (Common in Production)

Load from multiple sources with defined priority:

Priority 1: Cloud secrets store (AWS Parameter Store / Vault)
Priority 2: config.yaml file
Priority 3: Environment variables
Priority 4: Application defaults

Higher priority sources override lower ones. Allows environment-specific overrides without touching code.


5. Environment-Specific Configuration

Each environment has different priorities β€” config should reflect that.

EnvironmentPriorityConfig characteristics
Development (localhost)Developer productivity, debugginglog_level: debug, pool_size: 10, local DB URL
Test / CIAutomated validation, reproducibilityIsolated test DB, mock API keys
StagingMirror production behavior, minimize costCloud DB (smaller), pool_size: 2, production-like URLs
ProductionReliability, security, performancelog_level: info, pool_size: 50, real secrets from vault

Key insight: The same codebase runs in all environments. Only the config changes β€” no code changes needed to move between environments.


6. Security Best Practices

Never Hardcode Secrets

❌ const dbPassword = "super_secret_password"  // committed to git
βœ“  const dbPassword = process.env.DB_PASSWORD  // loaded at runtime

Database URLs, API keys, JWT secrets β€” none of these should ever appear in source code.

Use a Dedicated Secrets Management Service

When running at scale, a service like HashiCorp Vault or AWS Parameter Store handles:

  • Encryption at rest
  • Encryption in transit (TLS)
  • No plaintext secrets in environment or code

Principle of Least Privilege (Access Control)

RoleShould have access to
Frontend engineersFrontend API URLs, frontend SDK keys
Backend engineersDB credentials, Redis, Elasticsearch
DevOps / Infra teamCloud instance configs, Kubernetes secrets

No one should have access to everything. Segment access by role.

Rotate Secrets Periodically

API keys, JWT secrets, database passwords β€” rotate them on a schedule. A leaked secret that was rotated last week causes far less damage than one that’s been unchanged for 3 years.


7. The Most Important Practice: Validate Configs at Startup

If you take one thing from this topic: always validate your configuration before your server starts.

Why:

ScenarioWith validationWithout validation
Missing OPENAI_API_KEY in productionApp fails to start β†’ previous deployment keeps runningApp starts, fails at runtime when a user hits the AI feature β†’ 500 error
Misconfigured DB URLClear error at startup: β€œinvalid database URL”Cryptic connection errors at request time

How:

Before server.listen() / http.ListenAndServe():
  1. Load all configs from source
  2. Validate with a schema (Zod for TypeScript, go-validator for Go)
  3. Check required fields are present and correctly typed
  4. If any are missing β†’ log a clear error β†’ exit immediately

Blue-green deployment alignment: Most production deployments use blue-green β€” the old version only stops after the new version successfully starts. If your app fails to start due to config issues, the old version keeps running and users aren’t impacted.


8. Configuration Chaos β€” What to Avoid

Without a systematic config management strategy:

ProblemImpact
Hard-coded values scattered in codebaseChanging a value requires code change + deployment
Inconsistent behavior across environments”Works on my machine” β€” hard to reproduce prod issues
Secrets in source codeExposed in git history, logs, error messages
No validationSilent failures when configs are missing or wrong
No access controlAny developer can see production DB passwords

Quick Revision Checklist

  • Config management = all settings controlling how your app runs β€” not just secrets
  • Config types: application settings, database, external services, feature flags, security, performance, business rules
  • Classify configs: sensitive vs non-sensitive, environment-specific vs shared, frequently vs rarely changing
  • Storage options: env vars (.env + library), config files (YAML preferred over JSON for comments), cloud secrets services
  • Cloud secrets services: HashiCorp Vault, AWS Parameter Store, Azure Key Vault, Google Secret Manager
  • Hybrid strategy: load from multiple sources with defined priority
  • Environments: dev (debug/productivity), test (automation), staging (prod-mirror, lower cost), production (reliability/security)
  • Same codebase, different configs β†’ different behavior per environment, no code changes needed
  • Never hardcode secrets β€” always read from environment at runtime
  • Use cloud secrets management at scale β€” encryption at rest + in transit + access control
  • Principle of least privilege β€” frontend, backend, DevOps each get only what they need
  • Rotate secrets periodically (API keys, JWT secrets, DB passwords)
  • Validate all configs at startup β€” fail fast before serving users; use Zod (TS), go-validator (Go), or equivalent
  • Feature flags: enable/disable features without deployment; useful for A/B testing and regional rollouts
  • LOG_LEVEL=debug in dev, LOG_LEVEL=info in production β€” adjust verbosity per environment
  • DB pool size: small in local/staging (cost), large in production (traffic)