Environment Inheritance
Environment inheritance is Soup’s killer feature. Set values once, override where needed.
How It Works
Section titled “How It Works”When you get a secret from an environment, Soup:
- Checks if the secret exists in that environment
- If not, checks the parent environment
- Continues up the chain until found or reaches the root
base (DB_HOST=localhost, DB_PORT=5432)└── production (DB_HOST=prod-db.internal)In this example:
production.DB_HOST=prod-db.internal(overridden)production.DB_PORT=5432(inherited from base)
Setting Up Inheritance
Section titled “Setting Up Inheritance”Create Parent First
Section titled “Create Parent First”# Create the root environmentsoup env create my-app base
# Create children with --parentsoup env create my-app development --parent basesoup env create my-app production --parent baseMulti-Level Inheritance
Section titled “Multi-Level Inheritance”You can have multiple levels:
soup env create my-app basesoup env create my-app staging --parent basesoup env create my-app preview-123 --parent staging # Inherits from stagingbase└── staging └── preview-123preview-123 inherits from staging, which inherits from base.
Common Patterns
Section titled “Common Patterns”Pattern 1: Base + Environments
Section titled “Pattern 1: Base + Environments”The simplest and most common pattern:
# Create structuresoup env create api basesoup env create api dev --parent basesoup env create api staging --parent basesoup env create api prod --parent base
# Set shared config in basesoup set api base APP_NAME "My API"soup set api base LOG_FORMAT jsonsoup set api base CACHE_TTL 300
# Override per environmentsoup set api dev DEBUG truesoup set api prod LOG_LEVEL warnsoup set api prod CACHE_TTL 3600Pattern 2: Tiered Environments
Section titled “Pattern 2: Tiered Environments”For more complex setups:
# Create structuresoup env create api basesoup env create api nonprod --parent basesoup env create api dev --parent nonprodsoup env create api staging --parent nonprodsoup env create api prod --parent base
# Set in basesoup set api base APP_NAME "My API"
# Set in nonprod (applies to dev and staging)soup set api nonprod DEBUG truesoup set api nonprod DB_HOST localhost
# Override for prodsoup set api prod DB_HOST prod-db.internalbase├── nonprod│ ├── dev│ └── staging└── prodPattern 3: Feature Branches
Section titled “Pattern 3: Feature Branches”For PR preview environments:
# Create base structure oncesoup env create api basesoup env create api staging --parent base
# For each PR, create a preview envsoup env create api preview-pr-123 --parent stagingsoup set api preview-pr-123 API_URL "https://pr-123.preview.example.com"
# Clean up when PR is mergedsoup env delete api preview-pr-123Viewing Inheritance
Section titled “Viewing Inheritance”See Where a Value Comes From
Section titled “See Where a Value Comes From”soup get api prod DATABASE_URL --verbose# Output:# Source: base (inherited)List All Values with Sources
Section titled “List All Values with Sources”soup list api prod --show-source# Output:# APP_NAME = My API [base]# DB_HOST = prod-db [prod]# DATABASE_URL = postgres://... [base]List Only Local Values
Section titled “List Only Local Values”soup list api prod --local# Only shows values set directly in prodOverriding Values
Section titled “Overriding Values”Override a Value
Section titled “Override a Value”Simply set it in the child environment:
# Base has LOG_LEVEL=infosoup set api prod LOG_LEVEL warn# Now prod has LOG_LEVEL=warn, others still have infoRemove an Override
Section titled “Remove an Override”Delete the local value to restore inheritance:
# prod was overriding LOG_LEVELsoup delete api prod LOG_LEVEL# Now prod inherits LOG_LEVEL from base againCheck if Overridden
Section titled “Check if Overridden”soup get api prod LOG_LEVEL --verbose# Shows if the value is local or inheritedBest Practices
Section titled “Best Practices”1. Keep Base Minimal
Section titled “1. Keep Base Minimal”Only put truly shared config in base:
# Good - same everywheresoup set api base APP_NAME "My API"soup set api base LOG_FORMAT json
# Bad - probably different in prodsoup set api base DATABASE_URL "postgres://localhost/mydb"2. Use Sensible Defaults
Section titled “2. Use Sensible Defaults”Set safe defaults in base, override for prod:
soup set api base DEBUG truesoup set api base LOG_LEVEL debugsoup set api base RATE_LIMIT 1000
soup set api prod DEBUG falsesoup set api prod LOG_LEVEL infosoup set api prod RATE_LIMIT 1003. Document Your Structure
Section titled “3. Document Your Structure”Create a soup.md in your repo documenting your environment structure and key overrides.
4. Use References with Inheritance
Section titled “4. Use References with Inheritance”Combine inheritance with variable references:
# Base defines the templatesoup set api base DB_HOST localhostsoup set api base DB_PORT 5432soup set api base DB_NAME myappsoup set api base DATABASE_URL 'postgres://${DB_HOST}:${DB_PORT}/${DB_NAME}'
# Prod only overrides what's differentsoup set api prod DB_HOST prod-db.internal# DATABASE_URL automatically becomes postgres://prod-db.internal:5432/myapp