terrascale

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2026 License: MIT

README

TerraScale

Multi-tenant lifecycle manager for Terraform.

TerraScale wraps your existing Terraform project to provision, manage, and destroy isolated tenants — each with their own state file and configuration. No code duplication. No manual state management. No custom scripts.

terrascale add city-hospital --var project_name=emr-city --var subdomain=city-hospital

One command. Fully isolated tenant. Done.


The Problem

Every team that uses Terraform eventually needs to replicate their infrastructure for a second tenant, environment, or client. The options are all bad:

  • Copy-paste the project folder — drifts apart within weeks
  • Terraform workspaces — no registry, no visibility, one wrong destroy wrecks everything
  • Custom bash scripts — only the author understands them

TerraScale solves this. It treats your entire Terraform project as a "stamp" and provisions it repeatedly with different variables and isolated state.

Installation

Homebrew (macOS / Linux)
brew install 01x-in/tap/terrascale
From Source
go install github.com/01x-in/terrascale/cmd/terrascale@latest
Build Locally
git clone https://github.com/01x-in/terrascale.git
cd terrascale
make build
From Release

Download the binary for your platform from the Releases page.

Quick Start (5 Minutes)

# 1. Navigate to any existing Terraform project
cd examples/terrascale-site

# 2. Initialize TerraScale
terrascale init

# 3. Create terraform.tfvars for shared values (gitignored)
cat > terraform.tfvars <<EOF
project_name = "my-infra"
aws_region   = "us-east-1"
domain_name  = "example.com"
EOF

# 4. Add your first tenant
terrascale add tenant-1 --var subdomain=t1

# 5. Add a second tenant
terrascale add tenant-2 --var subdomain=t2

# 6. See what you've got
terrascale list

# 7. Inspect a tenant
terrascale inspect tenant-1

# 8. Tear one down (doesn't affect the other)
terrascale destroy tenant-1 --auto-approve

# 9. Confirm isolation
terrascale list

Commands

terrascale init

Scan a Terraform project and generate a terrascale.yaml configuration file.

terrascale init
  • Discovers all variables from .tf files
  • Interactive prompts to classify variables as tenant-specific or shared
  • Creates .terrascale/ directory and updates .gitignore
terrascale add <slug>

Provision a new tenant with isolated state.

terrascale add city-hospital \
  --var project_name=emr-city \
  --var subdomain=city-hospital \
  --environment production \
  --name "City General Hospital"
Flag Description Default
--var key=value Set a tenant variable (repeatable) —
--name Display name slug
--environment Environment type production
--auto-approve Skip confirmation prompt false

What happens under the hood:

  1. Resolves current AWS identity and asks for confirmation
  2. Creates .terrascale/state/<slug>/ for isolated state
  3. Reads shared variable values from terraform.tfvars
  4. Generates tenant.tfvars with all variables merged
  5. Generates backend override pointing to tenant's state directory
  6. Runs terraform init → plan → apply
  7. Captures outputs and saves everything to the registry
terrascale apply <slug>

Re-run terraform plan and apply for an existing tenant. Use this to retry a failed provisioning or pick up configuration changes.

terrascale apply production
terrascale apply production --auto-approve
Flag Description Default
--auto-approve Skip confirmation prompts false
terrascale list

Display all tenants in a table.

terrascale list
terrascale list --status=active
terrascale list --environment=production
terrascale list --json
Flag Description
--status Filter by status: active, destroyed, failed, provisioning
--environment Filter by environment
--json Output as JSON
terrascale inspect <slug>

Show full details for a tenant.

terrascale inspect city-hospital
terrascale inspect city-hospital --outputs-only
terrascale inspect city-hospital --json
terrascale inspect city-hospital --refresh
Flag Description
--outputs-only Show only Terraform outputs
--json Output as JSON
--refresh Run terraform refresh before showing
terrascale destroy <slug>

Destroy a tenant's infrastructure and clean up.

terrascale destroy city-hospital
terrascale destroy city-hospital --auto-approve
terrascale destroy city-hospital --keep-state
Flag Description Default
--auto-approve Skip confirmation (for CI/CD) false
--keep-state Preserve state directory for audit false

Configuration

TerraScale uses a single terrascale.yaml file as the source of truth. It tracks:

  • Project settings — Terraform directory, project mode
  • Tenant spec — which variables change per tenant, which are shared
  • Tenant registry — every tenant's slug, status, variables, outputs, and timestamps

Example:

version: "1"
project:
  name: my-infra
  terraform_dir: "."
  mode: root
state:
  backend: local
tenant_spec:
  tenant_variables:
    - name: subdomain
      type: string
      required: false
      prompt: Subdomain prefix for this tenant.
  shared_variables:
    - project_name
    - aws_region
    - domain_name
tenants: []

shared_variables lists variable names that are the same across all tenants. Their values are read at runtime from your project's terraform.tfvars — keeping sensitive or environment-specific values out of terrascale.yaml and out of version control.

# terraform.tfvars  (gitignored)
project_name = "my-infra"
aws_region   = "us-east-1"
domain_name  = "example.com"

If a shared variable isn't in terraform.tfvars, Terraform falls back to the default defined in variables.tf.

$slug in defaults — use $slug as a default value for any tenant variable and it will be automatically replaced with the tenant's slug at provisioning time:

tenant_variables:
  - name: project_name
    type: string
    required: true
    default: "$slug"
terrascale add city-hospital   # project_name defaults to "city-hospital"
terrascale add acme-corp       # project_name defaults to "acme-corp"

The user can still override it with --var project_name=something-else.

How It Works

TerraScale is a wrapper around the terraform binary. It never modifies your .tf files.

Your Terraform Project (the stamp)
  │
  ├── terrascale add hospital-a  →  .terrascale/state/hospital-a/
  ├── terrascale add hospital-b  →  .terrascale/state/hospital-b/
  └── terrascale add uat-march   →  .terrascale/state/uat-march/

Same code. Different variables. Isolated state. That's it.

Requirements

  • Go 1.22+ (to build from source)
  • Terraform >= 1.0 installed and on PATH

Project Structure

terrascale/
├── cmd/terrascale/          # CLI entry point
├── internal/
│   ├── cli/                 # Cobra commands
│   ├── config/              # YAML config structs + I/O
│   ├── terraform/           # TF binary wrapper, scanner, tfvars, state
│   ├── registry/            # Tenant CRUD
│   └── ui/                  # Terminal output helpers
├── examples/
│   └── terrascale-site/     # TerraScale website deployment project
├── terrascale.yaml          # Generated config (per-project)
└── .terrascale/             # Generated state directory (per-project)

Development

make build       # Build the binary
make test        # Run all tests
make install     # Install to $GOPATH/bin
make lint        # Run linter (requires golangci-lint)
make clean       # Remove built binary

License

MIT

Directories

Path Synopsis
cmd
terrascale command
internal
cli
ui

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL