terrascale

module
v0.2.1 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 initplanapply
  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