Environment Configuration
Environment-specific overrides and extensions for workspace deployments. Workspaces define WHAT infrastructure to build, environments define HOW to customize it for different deployment contexts (production, staging, development) without modifying workspace definitions.
Purpose
Consistent workspace replication across environments
Environment-specific variable and secret values
Feature flag management per environment
Custom properties for environment metadata
Schema
apiVersion: strata.huybrechts.xyz/v1
kind: environment
meta:
name: <environment_name> # Required: ^[a-z][a-z0-9_]*$
annotations:
description: <description>
labels:
environment: <environment> # production, staging, development
version: "<version>"
spec:
properties: {} # Environment-specific settings
custom: {} # Organizational metadata
overrides: # Override workspace resources, modules, and providers
resources: [] # Resource-level overrides
modules: [] # Module-level overrides (images, chart versions, enabled state)
providers: [] # Provider-level overrides
remotes: [] # Remote reference overrides (pin version/tag/branch per environment)
properties: {} # Override workspace properties
includes: [] # Terraform file includes
variables: [] # Override/extend workspace variables
secrets: [] # Override/extend workspace secrets
features: {} # Feature flags
audit: # Audit event policy and sink routing
policy:
events: {} # Event type → enabled flag
sinks: [] # Where to send audit events
structure: by-execution # Deploy-log directory layout
deploy_log_path: null # Custom deploy-log base path (default: .strata/deploy-log)
Properties & Custom
Properties - Environment-specific configuration:
properties:
debug_mode: false
log_level: "INFO"
backup_enabled: true
Custom - Organizational metadata:
custom:
costcenter: "PROD-INFRA-001"
owner: "Platform Team"
compliance: "PCI-DSS"
backup_retention_days: 30
Overrides
Environment overrides let you customize workspace resources, modules, and providers without modifying their source definitions. All override fields are optional — only specify what you need to change.
Module Overrides
Override module settings per environment: enable/disable modules, pin container image versions, pin Helm chart versions, or merge additional configuration.
spec:
overrides:
modules:
- module: xyz_backend # Module meta.name (required)
services: # Override service container images
- name: server
image: registry.omp.com/product/backend:2025.3.0
- name: worker
image: registry.omp.com/product/backend:2025.3.0
- module: xyz_frontend
chart_version: "26.1.0" # Pin Helm chart version
services:
- name: app
image: registry.omp.com/product/frontend:2025.3.0
- module: xyz_monitoring
enabled: false # Disable in this environment
Scoping: When a module appears in multiple resources or slots, use optional qualifiers to narrow the override:
overrides:
modules:
- module: xyz_backend # Applies to ALL instances
services:
- name: server
image: registry.omp.com/product/backend:2025.3.0
- module: xyz_backend # Narrow to canary slot only
slot_type: canary
services:
- name: server
image: registry.omp.com/product/backend:2025.3.0-rc.3
- module: xyz_backend # Narrow to specific resource
resource: kubernetes_cluster
services:
- name: server
image: registry.omp.com/product/backend:2025.3.0
Field |
Required |
Description |
|---|---|---|
|
Yes |
Module |
|
No |
Narrow to module within this resource |
|
No |
Narrow to module within this namespace |
|
No |
Narrow to specific slot ( |
|
No |
Enable or disable the module |
|
No |
Override Helm chart version |
|
No |
List of service image overrides ( |
|
No |
Arbitrary configuration merged into module config |
Constraints:
resourceandnamespaceare mutually exclusiveService names within a module override must be unique
When multiple overrides match, the most specific one wins (resource/namespace > module-only)
Resource Overrides
Override resource-level settings such as instance count, enabled state, or configuration:
spec:
overrides:
resources:
- resource: manager
count: 3
enabled: true
configuration:
instance_type: "Standard_D4s_v3"
Provider Overrides
Override the provider file binding or individual provider properties per environment.
Swap the entire provider file (file) — the provider’s spec.properties, spec.references,
and all other settings come from the replacement file. This is the recommended approach for
targeting different regions or cloud accounts:
# env-dev-eu.yaml
spec:
overrides:
providers:
- provider: azure
file: "@config/providers/azure-westeurope.yaml" # replaces workspace binding for this env
# env-dev-us.yaml
spec:
overrides:
providers:
- provider: azure
file: "@config/providers/azure-eastus.yaml"
Override individual properties (configuration) — applied on top of whichever provider
file is loaded (after file resolution if both are set). Useful for minor per-environment
tweaks without maintaining separate provider files:
spec:
overrides:
providers:
- provider: azure
configuration:
region: westeurope # overrides spec.properties.region in the loaded provider file
Configuration keys that do not match known spec.properties fields are logged and skipped.
Field |
Required |
Description |
|---|---|---|
|
Yes |
Must match a provider |
|
No |
Replace the workspace’s provider file binding for this environment |
|
No |
Overrides the description on the workspace provider reference |
|
No |
Key-value overrides applied to |
The provider YAML file defines which variable/secret keys are required; the actual credential
values are supplied via deployment variables and secrets — which can differ per deployment.
Remote Reference Overrides
Each remote’s base reference (default version, tag, or branch) is defined once in
configuration.spec.remotes[].reference. This is the version used for every environment
unless an override is present.
To use a different version in a specific environment, add an entry under
spec.overrides.remotes. The remote name must match an entry in configuration.spec.remotes.
# configuration.yaml — defines the base reference used when no override is present
spec:
remotes:
- name: tf_landscape
type: gitops
repository: https://github.com/org/tf-landscape.git
reference: main # ← base/default for all environments
source_path: terraform
# env-prd.yaml — pins production to a specific release tag
spec:
overrides:
remotes:
- remote: tf_landscape # must match configuration spec.remotes[].name
reference: v1.2.3 # overrides the base reference for this environment only
Resolution chain (highest to lowest priority):
Environment
spec.overrides.remotes[name].reference— per-environment pinConfiguration
spec.remotes[name].reference— base/default for all environments
Design note: The base reference is intentionally defined in one place (configuration) and overridden per environment. There is no module-level version pin — versioning is a deployment concern, not a module concern.
At build time the remote is fetched, the working tree is verified clean, and the ref is checked out in detached-HEAD mode. The resolved commit SHA is logged.
Validation:
Each
remotename must exist inconfiguration.spec.remotes(Phase 2 cross-validation — build fails if not found)Duplicate remote names within one environment are rejected at parse time
Build Output File Overrides (Terraform)
An environment can append extra output file definitions on top of the workspace
provisioner’s output.files[]. This is additive only — environments cannot remove or
replace workspace-level file definitions.
spec:
overrides:
output_files:
- name: compliance.auto.tfvars.json
variable: compliance_config
type: object
source: properties
key: compliance_config
- name: tenant_overrides.auto.tfvars.json
type: script
script: "@my_repo/scripts/build_tenant_overrides.py"
Use this when certain environments require extra Terraform variables not present in other environments — for example, a production-only compliance config or a tenant-specific override file.
Variables
Environment-specific variables override or extend workspace variables:
variables:
- key: ENVIRONMENT # UPPER_SNAKE_CASE
source: constant # constant, env, file, computed
value: production
Merging: Same key overrides workspace, new keys extend workspace.
Secrets
Environment-specific secrets override or extend workspace secrets:
secrets:
- key: DATABASE_PASSWORD
source: bitwarden # bitwarden, vault, env, file
value: prod-db-password-id
Merging: Same key overrides workspace, new keys extend workspace.
Features
Feature flags for environment-specific capabilities:
features:
monitoring_enabled: true
debug_logging: false
auto_scaling: true
canary_deployments: false
Audit
spec.audit configures which events are written to the deploy-log and where they are forwarded.
Settings are merged across all environments[] listed in the deployment (later entries override earlier ones).
Event Policy
Control which event types are active:
audit:
policy:
events:
deploy_audit: true # Every deploy execution (default: on)
cli_action: true # CLI command invocations (default: on)
policy_violation: true # Policy rule failures (default: on)
secret_access: true # Secret reads at build/deploy time (default: on)
lock_event: false # Deploy-lock acquire/release (default: off)
validation_result: false # Validate command outcomes (default: off)
drift_alert: false # Infrastructure drift detections (default: off)
build_event: false # Build command outcomes (default: off)
Sinks
Each sink routes audit events to a destination. Multiple sinks can be active simultaneously.
Built-in sink types
Type |
Required fields |
Optional fields |
Notes |
|---|---|---|---|
|
— |
— |
Human-readable to terminal |
|
|
— |
Appends one JSON object per line |
|
|
|
UDP/TCP to |
|
|
|
HTTP POST, JSON body |
audit:
sinks:
- name: local_log
type: ndjson
path: .strata/audit.ndjson
- name: ops_syslog
type: syslog
address: "10.0.0.5:514"
format: cef # Common Event Format for SIEM ingestion
- name: alert_hook
type: webhook
url: "https://hooks.example.com/strata"
headers:
Authorization: "Bearer ${WEBHOOK_TOKEN}"
events: [policy_violation] # Only forward violations
Integration-backed sinks (SIEM)
Reference a named SIEM integration declared in configuration.spec.integrations:
audit:
sinks:
- name: splunk
integration: splunk_hec # Must match configuration.spec.integrations[].name
- name: elk_stack
integration: elk_logstash
events: [deploy_audit, policy_violation]
See configuration.md for how to declare Splunk, ELK, OpenTelemetry, and Azure Sentinel integrations.
Deploy-Log Structure
Controls the directory layout under the deploy-log base path:
Value |
Path template |
|---|---|
|
|
|
|
|
|
|
|
|
|
audit:
structure: by-execution # default
deploy_log_path: logs/deploy # relative to workspace root (default: .strata/deploy-log)
Forwarding via CLI
Re-forward deploy-log entries to a SIEM integration without re-deploying:
strata audit export --siem splunk_hec
strata audit export --siem splunk_hec --out export.json # also write JSON file
Sink field reference
Field |
Type |
Default |
Description |
|---|---|---|---|
|
string |
— |
Unique sink name |
|
string |
— |
Built-in type: |
|
string |
— |
SIEM integration name (mutually exclusive with |
|
bool |
|
Toggle sink without removing it |
|
string[] |
all |
Event type filter ( |
|
string |
— |
Output file path ( |
|
string |
— |
|
|
string |
|
Payload format: |
|
string |
— |
POST target URL ( |
|
map |
— |
HTTP headers ( |
Examples
Production:
meta:
name: production
labels:
environment: production
spec:
properties:
log_level: "WARN"
backup_enabled: true
custom:
costcenter: "PROD-INFRA-001"
owner: "Platform Team"
sla: "99.9%"
variables:
- key: ENVIRONMENT
source: constant
value: production
- key: REPLICA_COUNT
source: constant
value: 5
secrets:
- key: DATABASE_PASSWORD
source: bitwarden
value: prod-db-password-id
features:
auto_scaling: true
monitoring: true
debug_mode: false
Staging:
meta:
name: staging
labels:
environment: staging
spec:
properties:
log_level: "INFO"
variables:
- key: ENVIRONMENT
source: constant
value: staging
- key: REPLICA_COUNT
source: constant
value: 3
secrets:
- key: DATABASE_PASSWORD
source: bitwarden
value: staging-db-password-id
features:
monitoring: true
canary_deployments: true
Development:
meta:
name: development
labels:
environment: development
spec:
properties:
log_level: "DEBUG"
backup_enabled: false
variables:
- key: ENVIRONMENT
source: constant
value: development
- key: REPLICA_COUNT
source: constant
value: 1
secrets:
- key: DATABASE_PASSWORD
source: constant
value: dev_password_123
features:
debug_mode: true
hot_reload: true
Workspace & Environment Relationship
Workspace (WHAT to build):
# workspace.yaml
spec:
topology:
- name: cluster
components:
- name: worker
resource:
count: ${REPLICA_COUNT} # Parameterized
variables:
- key: REPLICA_COUNT
source: constant
value: 1 # Default
Environment (HOW to customize):
# production.yaml - Override REPLICA_COUNT to 5
spec:
variables:
- key: REPLICA_COUNT
source: constant
value: 5
# development.yaml - Keep REPLICA_COUNT at 1
spec:
variables:
- key: REPLICA_COUNT
source: constant
value: 1
Multi-file Composition
A deployment can list multiple environment files under spec.environments. strata merges
them left-to-right before applying overrides to the workspace. Later files win on conflict.
# deploy-prd.yaml
spec:
environments:
- environments/base.yaml # shared baseline
- environments/eu-region.yaml # region-specific settings
- environments/prd.yaml # production overrides — highest precedence
Per-section merge strategy
Section |
Strategy |
|---|---|
|
Last-wins by |
|
Last-wins by |
|
Last-wins by |
|
Shallow |
|
Shallow |
|
Last-wins (wholesale) |
|
Last-wins (wholesale) |
|
Last-wins by |
|
Last-wins by |
|
Last-wins by |
|
Last-wins by |
|
Shallow |
|
Append, deduplicated by |
|
Append, deduplicated by output |
Single-file deployments follow the same rules — they simply produce an unchanged result.
See Environment Composition for patterns and examples.
Configuration Merge Order
Workspace defaults (base)
Environment overrides (override/extend)
Runtime parameters (CLI args)
Merge strategy: Variables/secrets with the same key override; new keys extend. Properties and custom use shallow dict merge. See the composition section above for the full per-section table when multiple environment files are listed.
Use Cases
Multi-environment deployment:
config/
├── workspaces/platform.yaml # Infrastructure (WHAT)
└── environments/
├── production.yaml # Prod config (HOW)
├── staging.yaml # Staging config (HOW)
└── development.yaml # Dev config (HOW)
Regional deployments:
# us-east.yaml
spec:
variables:
- key: REGION
source: constant
value: us-east-1
# eu-west.yaml
spec:
variables:
- key: REGION
source: constant
value: eu-west-1
Feature flags:
# production.yaml
spec:
features:
new_dashboard: false # Not ready
legacy_api: true # Keep compatibility
# staging.yaml
spec:
features:
new_dashboard: true # Test in staging
beta_features: true # Enable for testing
CLI Integration
# Validate a deployment YAML file
strata validate repos/xyz-infrastructure/deployments/xyz-deploy-prd.yaml
# Deploy using the active profile's environment refs
strata deploy run -f repos/xyz-infrastructure/deployments/xyz-deploy-prd.yaml
# Dry-run (plan only — no changes applied)
strata deploy run -f repos/xyz-infrastructure/deployments/xyz-deploy-prd.yaml --dry-run
# Tear down infrastructure
strata deploy destroy -f repos/xyz-infrastructure/deployments/xyz-deploy-prd.yaml --dry-run
File Location
Environment files should be in:
config/environments/<environment_name>.yaml
Examples:
config/environments/production.yamlconfig/environments/staging.yamlconfig/environments/development.yaml
Best Practices
Naming: Use deployment stage names (
production,staging,development)Consistent structure: Same structure across environment files
Secret management: Use appropriate secret managers per environment
Minimal overrides: Only override what’s necessary
Default values: Set sensible defaults in workspace
Testing: Test environment configs in lower environments first
Documentation: Document overrides and purpose
Version control: Track environment files (exclude sensitive data)
Validation
Platform validates:
Valid environment name (lowercase, alphanumeric, underscores)
Unique variable keys within environment
Unique secret keys within environment
Valid variable/secret sources
Troubleshooting
Validation failed: Check required fields, verify unique keys, ensure valid sources
Variable not overriding: Verify key matches workspace variable exactly (case-sensitive), check environment file specified in CLI
Secret not found: Ensure source configured correctly, verify secret ID/path exists, check secret manager authentication
Feature flag not working: Verify feature name referenced correctly in code, check environment file loaded
Environment vs Workspace
Aspect |
Workspace |
Environment |
|---|---|---|
Purpose |
Define infrastructure structure |
Customize for deployment context |
Scope |
What to build |
How to configure |
Changes |
Infrastructure changes |
Configuration changes |
Reusability |
Single definition |
Multiple environments |
Frequency |
Changes infrequently |
Changes per deployment |
Summary
Environment configurations enable consistent infrastructure replication across deployment contexts by providing variable/secret overrides, feature flag management, and custom properties. This separation allows a single workspace to deploy to multiple environments with appropriate customizations.