Skip to main content
Pulumi logo Pulumi logo
  1. Docs
  2. Internal Developer Platform
  3. Guides
  4. Best Practices
  5. Patterns
  6. One ESC environment per lifecycle stage

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.

      The infrastructure as code platform for any cloud.