Cloud and infrastructure as code
Environments and parity
Most teams need only a few environments. Each long-lived one adds cost and drift. Parity, meaning the same shape, is what makes a staging test count as evidence.
An environment is a complete place to run your software, such as a laptop, a test stack or production. Every long-lived environment costs money, drifts from the others and needs its own migrations. The question is how few you can get away with, and how closely the ones you keep match production.
The ladder
A workable ladder for a small product team looks like this.
| Environment | Purpose | Lifetime |
|---|---|---|
| Local | Development loop and unit tests | Developer machine |
| Preview (ephemeral) | One stack per pull request | Hours to days; destroyed on merge |
| Staging | Production-like integration, migration rehearsal, QA | Long-lived |
| Production | Paying users | Long-lived |
Some teams add a shared dev environment between local and staging, or a disaster-recovery standby of production. Each long-lived environment multiplies the cost and the migration work.
Trade-off
More environments catch integration bugs earlier and give QA a stable place to work. Fewer environments cut spend and force parity, because you cannot paper over a bug in a fifth snowflake. Add another long-lived environment only when a concrete workflow demands it, such as a regulated approval step or a partner sandbox.
Parity means the same shape
Parity does not mean identical instance sizes. It means the same shape. Staging can be smaller and single-zone. It should use the same major database engine version, the same authentication mode, the same queue semantics and the same feature-flag evaluation path.
Fine: staging is 1 zone, 2 small nodes, Postgres 16
Not fine: staging runs SQLite while production runs Postgres 16
Not fine: staging skips TLS while production requires itEphemeral previews
Ephemeral environments are built from infrastructure as code and your CI pipeline. Open a pull request and get a URL. The app runs against a throwaway database, where you can exercise migrations. On merge, the stack is torn down. That replaces "please don't break the shared dev database".
Common mistakes
- Keeping many long-lived environments. Each one drifts and needs care.
- Making staging a different shape. It then passes bugs that production will fail.
- Sharing a dev database across pull requests. One PR's changes break another's tests.
Check yourself
- What is the difference between parity and identical sizing? Answer: Parity is about the same shape, such as engine, auth and queue behaviour. Size can differ.
- Why are ephemeral previews better than one shared dev database? Answer: Each preview is isolated, so one change cannot corrupt another's data.
Key takeaways
- Keep a small ladder: local, ephemeral previews, one staging, production.
- Parity means the same shape. Size can be smaller.
- Ephemeral environments built from code replace shared dev databases.
Further learning
Next, see how the settings themselves are layered and validated when the app starts: config layering and validation.
Related
Configuration, environments and feature flags
Twelve-factor config, environment parity, secrets injection, feature flags and the blast radius of a bad config push.
Continuous integration and the software supply chain
Fast, trustworthy pipelines - build, test, artifact, scan and sign - plus DORA metrics and supply-chain controls that keep trunk green.
Infrastructure as code with Terraform
Declaring infrastructure in code — providers, state, plans, modules, environments and the habits that keep apply safe.