Terraform Commands

The stategraph tf command group plans and applies Terraform changes through Stategraph. These commands replace terraform plan and terraform apply — Stategraph computes the plan scope from your change, runs the underlying Terraform binary, and records everything in a transaction.

Two top-level aliases save typing: stategraph plan is stategraph tf plan, and stategraph apply is stategraph tf apply.

Commands

Command Description
stategraph tf plan Plan changes by comparing local HCL against the current state
stategraph tf apply Apply a saved plan file, or plan and apply in one step
stategraph tf show Re-display a plan file, optionally as JSON
stategraph tf mtx Plan across multiple states in a single atomic transaction

The classic workflow is plan-then-apply: plan --out writes a plan file, you review it, then apply commits it. --out is optional — without it, plan just shows a read-only preview. You can also skip the saved plan entirely and run stategraph tf apply with no plan file to plan, review the diff, and apply in one step.

# From your root module directory
stategraph tf plan --tenant <tenant-id> --out plan.json
stategraph tf apply plan.json

See Velocity Setup for the end-to-end onboarding flow, including importing your existing state first.

stategraph tf plan

Plan Terraform changes by comparing local HCL against the current state in Stategraph. Outputs a plan file for review before applying. Run it from your root module directory — the state is auto-discovered from stategraph.json if --state is not passed.

stategraph tf plan --tenant <tenant-id> [--out <plan-file>] [options]

Options

Option Required Description
--tenant Yes Tenant ID (UUID), or set STATEGRAPH_TENANT_ID
--out No File to save the plan to for a later stategraph tf apply. When omitted, the plan is shown as a read-only preview and no plan file is written.
--state No State ID (auto-discovered from stategraph.json if not set)
--workspace No Workspace name (default: "default")
--var No Set a variable (key=value, repeatable)
--var-file No Path to a variable file
--force No Force a node address into the plan; supports globs (e.g., data.*). Repeatable.
--force-files No Attach all files matching a path glob (e.g., '**/*.yml') to every file() / templatefile() / fileset() call — an escape hatch for paths Stategraph cannot resolve statically. Repeatable.
--skip-refresh No Skip the state refresh (passes -refresh=false to the underlying terraform plan)
--skip-costs No Skip fetching the cost-delta preview after the plan diff
--costs-wait No Maximum seconds to wait for the cost delta (default: 3). Cannot be combined with --skip-costs.
--batch-size No Batch size for transaction log appends (performance tuning)
--parallel-batches No Number of parallel batches for transaction log appends (performance tuning)
--detailed-exitcode No Return tofu/terraform-compatible exit codes (for CI scripting)

Pass the same --var / --var-file flags you use with terraform plan.

Example

stategraph tf plan --tenant 550e8400-e29b-41d4-a716-446655440000 --out plan.json

The plan output ends with the familiar summary line, followed by a cost preview when cost analysis is configured:

Plan: 1 to add, 0 to change, 0 to destroy.

Costs:
  Totals:
    Monthly:  130.82 USD → 140.16 USD   (+9.34 USD)
    ...

If the cost preview is not ready within --costs-wait seconds, the plan prints a hint pointing at stategraph tx costs instead — see Plan-Time Cost.

Forcing resources into a plan

By default, Stategraph plans only what your change touches. --force widens the plan to additional addresses:

# Re-plan every data source
stategraph tf plan --tenant <tenant-id> --out plan.json --force 'data.*'

# Force one module into the plan
stategraph tf plan --tenant <tenant-id> --out plan.json --force 'module.networking.*'

stategraph tf apply

Apply Terraform changes. With a saved plan file, apply commits a plan generated earlier by stategraph tf plan --out. With no plan file, it runs a fresh plan, shows the diff, and prompts for approval before committing — a one-step alternative to the plan-then-apply flow.

stategraph tf apply [options] [<plan-file>]

Arguments

Argument Required Description
<plan-file> No Plan file produced by stategraph tf plan or stategraph tf mtx. When omitted, apply runs a fresh plan, shows the diff, and prompts for approval before committing.

Options

Option Required Description
--skip-revision-check No Skip the revision hash check between plan and apply

The plan file records the state revision it was computed against. If the state changed between plan and apply, apply refuses to run so you never apply a stale plan — re-plan instead. --skip-revision-check overrides this guard.

Applying without a plan file

When you omit the <plan-file> argument, stategraph tf apply runs a fresh plan, shows the diff, and prompts for approval before committing — the same one-step flow as terraform apply. Pass --auto-approve to skip the prompt:

stategraph tf apply --tenant <tenant-id> --auto-approve

The approval prompt requires an interactive terminal. With a non-tty stdin or --silent (STATEGRAPH_SILENT), the apply fails unless --auto-approve is also given — combine --silent with --auto-approve to apply non-interactively in CI.

In this plan-less form, apply accepts the same flags as stategraph tf plan to configure the fresh plan it runs: --tenant, --state, --workspace, --var, --var-file, --force, --force-files, --skip-refresh, --skip-costs, --costs-wait, --batch-size, and --parallel-batches. When a saved plan file is supplied these flags are unnecessary — the plan already captured those choices — and several are rejected as a usage error.

Example

stategraph tf apply plan.json

stategraph tf show

Show a previously generated plan file. By default it re-displays the plan in human-readable form; with --json it emits the plan as JSON with all names unmangled, which is useful for policy checks and tooling.

stategraph tf show [options] <plan-file>

Options

Option Required Description
--json No Emit the plan as JSON

Example

# Review a plan again before applying
stategraph tf show plan.json

# Feed the plan into tooling
stategraph tf show --json plan.json | jq '.'

stategraph tf mtx

Plan Terraform changes across all workspaces in each given directory's group, in a single atomic transaction. Either every state applies or none do. Each directory must contain a stategraph.json.

stategraph tf mtx --tenant <tenant-id> --out <plan-file> [options] <dir>...

Arguments

Argument Required Description
<dir>... Yes One or more directories containing stategraph.json

Options

Option Required Description
--tenant Yes Tenant ID (UUID), or set STATEGRAPH_TENANT_ID
--out Yes File to write the plan to
--force No Force a node address into the plan; supports globs. Repeatable.
--skip-refresh No Skip the state refresh during plan
--skip-costs No Skip fetching the cost-delta preview
--costs-wait No Maximum seconds to wait for the cost delta (default: 3)
--batch-size No Batch size for transaction log appends (performance tuning)
--parallel-batches No Number of parallel batches for transaction log appends (performance tuning)
--detailed-exitcode No Return tofu/terraform-compatible exit codes (for CI scripting)

Example

stategraph tf mtx --tenant <tenant-id> --out plan.json ./networking ./compute ./application
stategraph tf apply plan.json

See Multi-State Transactions for cross-state dependency semantics and guarantees.

Configuration

By default, the plan and apply stages execute tofu (OpenTofu). Set the TF_CMD environment variable to use a different binary, such as terraform.

Environment Variable Description
TF_CMD Path to the Terraform/OpenTofu binary (default: tofu)
STATEGRAPH_TENANT_ID Tenant ID (alternative to --tenant)
STATEGRAPH_WORKSPACE Workspace name (alternative to --workspace)
STATEGRAPH_COSTS_WAIT_SECONDS Deployment-level default for --costs-wait
STATEGRAPH_TX_BATCH_SIZE Default for --batch-size
STATEGRAPH_TX_PARALLEL_BATCHES Default for --parallel-batches

Next Steps