Variable References
Variable references let you build values from other values, reducing duplication and making updates easier.
Basic Syntax
Section titled “Basic Syntax”Use ${VAR_NAME} to reference another secret:
soup set api base DB_HOST localhostsoup set api base DB_PORT 5432soup set api base DATABASE_URL 'postgres://${DB_HOST}:${DB_PORT}/mydb'When you get DATABASE_URL, Soup resolves the references:
soup get api base DATABASE_URLResolution Rules
Section titled “Resolution Rules”Same Environment First
Section titled “Same Environment First”References are resolved within the same environment context:
# basesoup set api base DB_HOST localhost
# prodsoup set api prod DB_HOST prod-db.internalsoup set api prod DATABASE_URL 'postgres://${DB_HOST}:5432/mydb'
soup get api prod DATABASE_URL# Output: postgres://prod-db.internal:5432/mydbInheritance Applies
Section titled “Inheritance Applies”If a referenced variable isn’t in the current environment, inheritance kicks in:
# basesoup set api base DB_HOST localhostsoup set api base DATABASE_URL 'postgres://${DB_HOST}:5432/mydb'
# prod only overrides DB_HOSTsoup set api prod DB_HOST prod-db.internal
soup get api prod DATABASE_URL # DATABASE_URL inherited from base# Output: postgres://prod-db.internal:5432/mydb# The ${DB_HOST} in base's DATABASE_URL resolves to prod's DB_HOSTChained References
Section titled “Chained References”References can chain through multiple variables:
soup set api base HOST localhostsoup set api base PORT 5432soup set api base ENDPOINT '${HOST}:${PORT}'soup set api base URL 'postgres://${ENDPOINT}/mydb'
soup get api base URL# Output: postgres://localhost:5432/mydbCommon Patterns
Section titled “Common Patterns”Database Connection Strings
Section titled “Database Connection Strings”soup set api base DB_USER myappsoup set api base DB_PASSWORD secret123soup 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_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}'API Base URLs
Section titled “API Base URLs”soup set api base API_HOST api.example.comsoup set api base API_VERSION v1soup set api base API_BASE_URL 'https://${API_HOST}/${API_VERSION}'soup set api base USERS_URL '${API_BASE_URL}/users'soup set api base ORDERS_URL '${API_BASE_URL}/orders'Redis/Cache URLs
Section titled “Redis/Cache URLs”soup set api base REDIS_HOST localhostsoup set api base REDIS_PORT 6379soup set api base REDIS_PASSWORD ""soup set api base REDIS_URL 'redis://:${REDIS_PASSWORD}@${REDIS_HOST}:${REDIS_PORT}'AWS Resource Names
Section titled “AWS Resource Names”soup set api base AWS_REGION us-east-1soup set api base AWS_ACCOUNT_ID 123456789soup set api base S3_BUCKET 'my-app-${AWS_REGION}'soup set api base SQS_QUEUE 'arn:aws:sqs:${AWS_REGION}:${AWS_ACCOUNT_ID}:my-queue'Escaping
Section titled “Escaping”To use a literal ${...} without resolution, escape it:
soup set api base TEMPLATE 'Hello $${NAME}' # Note: double $
soup get api base TEMPLATE# Output: Hello ${NAME}Error Handling
Section titled “Error Handling”Undefined References
Section titled “Undefined References”If a referenced variable doesn’t exist, you get an error:
soup set api base URL '${UNDEFINED_VAR}'soup get api base URL# Error: Unresolved reference: ${UNDEFINED_VAR}Circular References
Section titled “Circular References”Soup detects circular references:
soup set api base A '${B}'soup set api base B '${A}'soup get api base A# Error: Circular reference detected: A -> B -> AMax Depth
Section titled “Max Depth”References are limited to 10 levels deep:
# If you have A -> B -> C -> ... -> K (11 levels)# Error: Max reference depth exceededResolution Modes
Section titled “Resolution Modes”Resolved (Default)
Section titled “Resolved (Default)”The CLI resolves references by default:
soup get api base DATABASE_URLUnresolved
Section titled “Unresolved”To see the raw value with ${...} intact:
soup get api base DATABASE_URL --raw# Output: postgres://${DB_HOST}:${DB_PORT}/mydbThe API accepts a resolve query parameter:
# Resolved (default)curl .../secrets?resolve=true
# Unresolvedcurl .../secrets?resolve=falseBest Practices
Section titled “Best Practices”1. Prefer Components Over Full URLs
Section titled “1. Prefer Components Over Full URLs”# Good - easy to override partssoup set api base DB_HOST localhostsoup set api base DB_PORT 5432soup set api base DATABASE_URL 'postgres://${DB_HOST}:${DB_PORT}/mydb'
# Less good - have to override the whole thingsoup set api base DATABASE_URL postgres://localhost:5432/mydb2. Use Consistent Naming
Section titled “2. Use Consistent Naming”Follow a pattern for component variables:
# Service_Component patternsoup set api base POSTGRES_HOST ...soup set api base POSTGRES_PORT ...soup set api base REDIS_HOST ...soup set api base REDIS_PORT ...3. Document Complex References
Section titled “3. Document Complex References”For chains of references, add comments in your project’s documentation.
4. Test Your References
Section titled “4. Test Your References”After setting up references, verify they resolve correctly:
soup list api prod --resolved