IDP Pattern: One ESC environment per lifecycle stage
Description
This pattern involves creating dedicated Pulumi ESC (Environments, Secrets, and Configuration) environments for each lifecycle stage of your application deployment pipeline, such as development, staging, and production. Each stage has its own environment with stage-specific configuration and secrets.
When to use this pattern
- Always-on services: When running SaaS applications, social media sites, or online stores with one primary instance
- Reliability focus: When uptime and reliability are critical business requirements
- Careful rollouts: When you need to test configuration changes through stages before production
- Single-instance applications: When you have one main production deployment rather than multiple customer instances
When NOT to use this pattern
- Multi-tenant applications: When you deploy separate instances for different customers
- Rapid iteration: When you need to deploy frequently without formal staging processes
- Cost-sensitive projects: When maintaining multiple environments is too expensive
How to use this pattern
This pattern works well with Pulumi ESC’s composition to share common configuration while allowing stage-specific overrides.
Example
Consider a SaaS application deployed across three stages:
# environments/development.yaml
values:
stage: "development"
app:
replicas: 1
logLevel: "debug"
database:
host: "dev-db.example.com"
ssl: false
secrets:
apiKey: "dev-api-key"
# environments/staging.yaml
values:
stage: "staging"
app:
replicas: 2
logLevel: "info"
database:
host: "staging-db.example.com"
ssl: true
secrets:
apiKey: "staging-api-key"
# environments/production.yaml
values:
stage: "production"
app:
replicas: 5
logLevel: "warn"
database:
host: "prod-db.example.com"
ssl: true
secrets:
apiKey: "prod-api-key"
Define a shared base environment with the configuration common to every stage:
# environments/base-config.yaml
values:
app:
name: "web-app"
database:
port: 5432
Each stack then composes the shared base with its stage-specific environment. Environments are referenced as <project>/<environment>, and you list them under the environment key of the stack configuration file. For example, assuming the environments above live in an ESC project named web-app, the production stack’s configuration file looks like this:
# Pulumi.production.yaml
environment:
- web-app/base-config
- web-app/production
Later environments in the list override earlier ones, so stage-specific values take precedence over the shared base.
This allows consistent base configuration while enabling stage-specific customization.
Related patterns
- IDP Pattern: One ESC environment per service - Can be combined for service-stage matrices
- IDP Pattern: One ESC environment per team - Can be combined for team-stage matrices
- IDP Pattern: Composable environments - For sharing base configuration across stages