Migrate TicketFlow's settings to the environment. No solutions.md before submitting.
Exercise 1 — Configuration audit
- List ALL your project's config: what sits in settings.py as literals, what reads from env vars, what lives in view/service code (a
requests.get("https://...")with a hardcoded URL is hidden config). - Classify each: code (doesn't vary), sensitive config (a secret), non-sensitive config (varies but isn't secret), and bad config (a literal that MUST vary and is nailed down).
- Move the bad config to the environment with safe defaults. The test:
git grep -n "https://" -- '*.py'returns only documentation URLs.
Exercise 2 — 12-factor settings.py
- Convert your settings.py into a single module with django-environ (or pydantic-settings): SECRET_KEY/DEBUG/ALLOWED_HOSTS/DATABASE_URL/REDIS_URL from the environment, safe defaults.
- Write the
.env.example(no real values) and the dev.env(gitignored). A teammate must be able to clone and boot with justcp.env.example.env+ local values. - The same-image proof: write the Dockerfile (40 goes deeper) with ONE image and boot 3 containers with 3.env files. Same image hash, three configs.
Exercise 3 — Dual rotation
- Implement
SECRET_KEYS(a list with new + optional old) and make the token/simplejwt validator accept any key in the list. - Write the rotation sequence as a 5-step checklist with the time window between step 2 (dual deploy) and 5 (retiring the old one). What happens to tokens issued with the old key during the window?
- Do the same for 17's
WEBHOOK_SECRET(HMAC verification accepts the new and the old key).
Exercise 4 — Fail-fast
- Add the boot validations (SECRET_KEY, ALLOWED_HOSTS, DATABASE_URL mandatory outside DEBUG) with
ImproperlyConfiguredand messages saying WHICH variable is missing and WHERE it is documented. - Smoke test:
manage.py check --deploywith a fake prod environment (vars set in the test) passes; with DJANGO_DEBUG=true in fake prod, it fails with a clear error. - Document in the README the "boot triage": the 3 most commonly missing variables and their exact symptom at boot.
Exercise 5 — Config as feature flags
- Add
FEATURE_WEBHOOKS(bool) andFEATURE_SAGA_V2(bool) as config flags (not code flags): read from the environment, default false, used withif settings.FEATURE_WEBHOOKS:in the service. - Write the test that runs the same test with the flag on and off. What does this gain over a git branch per environment?
Submit
Paste the settings.py, the.env.example, the rotation checklist and the smoke test. Next: Lesson 28 — Refactoring without breaking anything.