Skip to main content
ubx handles multi-environment infrastructure through extend blocks and the --env flag — no workspace duplication required.

Pattern

main.iac           # base definitions (staging defaults)
envs/
  prod/
    overrides.iac  # production overrides
  staging/
    overrides.iac  # staging-specific overrides

Base Definitions

main.iac:
input "env" {
  type    = "string"
  default = "staging"
}

unit "aws_rds_instance" "db" {
  engine            = "postgres"
  instance_class    = "db.t3.micro"   # staging default
  allocated_storage = 20
  multi_az          = false
  username          = "admin"
  password          = secret("aws_secrets_manager", "${input.env}/db/password")
  skip_final_snapshot = true
}

unit "aws_s3_bucket_v2" "assets" {
  bucket        = "${input.env}-assets"
  force_destroy = input.env != "prod"
}

Production Overrides

envs/prod/overrides.iac:
extend "unit" "aws_rds_instance" "db" {
  instance_class    = "db.r6g.2xlarge"
  allocated_storage = 100
  multi_az          = true
  skip_final_snapshot = false

  lifecycle {
    prevent_destroy = true
  }
}

Deploy by Environment

ubx plan               # staging preview
ubx plan --env prod    # production preview

ubx apply              # deploy staging
ubx apply --env prod   # deploy production

ubx.yaml Default Environment

project:    my-platform
backend:    file://.ubx/state
defaultEnv: staging    # used when --env is not specified

Conditional Resources

Use when to create resources only in specific environments:
unit "aws_cloudwatch_dashboard" "prod_monitoring" {
  when           = input.env == "prod"
  dashboard_name = "prod-overview"
  dashboard_body = jsonencode({ widgets = [] })
}

Default Tags per Environment

# ubx.yaml
default_tags:
  env:     "${input.env}"
  managed: "ubx"
  team:    "platform"
These tags are automatically applied to all taggable resources, with input.env resolving to the active environment.