cloud IaC terraform tfc claude-curated
Terraform Cloud (TFC) is HashiCorp’s managed SaaS for running Terraform — remote state, run pipelines, policy enforcement, a web UI. Workspaces are the primary unit of isolation: one workspace owns one state file, one set of variables, and one execution context.
Concepts
| Concept | What it is |
|---|---|
| Organization | Top-level tenant. Billing, SSO, teams attach here. |
| Project | A folder for grouping workspaces. Permissions and variable sets can scope to a project. |
| Workspace | A single Terraform configuration’s state + variables + run history. Roughly equivalent to one root module + one environment. |
| Variable Set | A reusable bag of variables applied across many workspaces. |
| Run | A single plan or plan + apply execution, tied to a workspace. |
A workspace in TFC is not the same as a Terraform CLI workspace (terraform workspace). CLI workspaces are alternate state files inside one backend; TFC workspaces are wholly separate runtimes.
Workspace types
TFC workspaces differ in how runs are triggered:
- VCS-driven — connected to a Git repository. Pushes to the tracked branch trigger speculative plans on PRs and apply runs on merge. The default for production workflows.
- CLI-driven — runs are kicked off by a developer running
terraform plan/applylocally. The CLI ships the config to TFC, which executes remotely. Useful when you want TFC’s state and policy gates without VCS automation. - API-driven — runs are triggered by external automation calling the TFC API (custom CI, an internal platform). Config is uploaded as a tarball.
A workspace can also be set to execution_mode = local, in which TFC stores state and variables but the run executes on the developer’s machine. This is a common compromise when a config needs local network access (e.g. a private VPN to reach a target API) but you still want centralised state. See Terraform CLI with Cloud Hybrid for the local/CLI-driven workflow.
Variables
TFC distinguishes two variable categories:
- Terraform variables — fed into
var.*references in the config. Equivalent to-varflags or a.tfvarsfile. - Environment variables — exported into the run’s process environment. Used for provider credentials (
AWS_ACCESS_KEY_ID), debug flags (TF_LOG), or anything Terraform itself reads from the env.
Each variable can be flagged:
- Sensitive — value is write-only after creation, masked in run output. Use for credentials and tokens.
- HCL — value is parsed as HCL rather than a string. Required for lists, maps, and objects.
Variable sets
A variable set is a named group of variables that can be attached to:
- The whole organisation (every workspace gets it),
- A project (every workspace in that project),
- An explicit list of workspaces.
Variable sets are how you avoid retyping the same AWS credentials or default region into every workspace. See CI CD for Terraform for surrounding pipeline patterns.
Precedence
When a key is defined both at the workspace level and via a variable set:
- Workspace-level value wins — the set provides the default; the workspace overrides it.
- Among sets, the global organisation set is overridden by a project-scoped set, which is overridden by a workspace-attached set.
- Inside a single run, command-line
-var(CLI-driven) overrides workspace and set values.
A frequent gotcha: marking a set variable as sensitive means you cannot inspect it to debug whether the workspace really overrode it. Treat precedence as a contract and document it.
Comparison to Terragrunt
Terragrunt solves a related problem (DRY config across many environments) but with a different shape:
| Dimension | Terraform Cloud | Terragrunt |
|---|---|---|
| State storage | Managed by TFC | You configure (S3+DynamoDB, GCS, etc.) — but Terragrunt generates the backend block per module so each has its own state |
| DRY mechanism | Variable sets, shared modules | HCL inheritance via include and terragrunt.hcl files |
| Run orchestration | TFC pipelines + VCS triggers | CLI only — terragrunt run-all plan walks the dependency tree |
| Policy / governance | Sentinel or OPA, drift detection (paid) | None built in; bring your own (Atlantis, OPA, custom) |
| Cost | Per-resource pricing, can be steep at scale | Free, open source |
| Coupling | Tied to HashiCorp’s SaaS | Cloud-agnostic, self-hosted |
When to pick TFC: small to medium estates where the team values the web UI, run history, PR integration, and Sentinel policy without operating it themselves.
When to pick Terragrunt: many similar environments (region × env matrices), strong preference for self-hosted state, or cost sensitivity at scale. Terragrunt’s per-module backend isolation also reduces blast radius — corrupting one state file doesn’t take down the org.
The two aren’t mutually exclusive: Terragrunt can call modules whose backend points at TFC’s remote backend, getting Terragrunt’s DRY config plus TFC’s state and policy. Most teams pick one or the other for simplicity.
State storage: TFC vs S3 + DynamoDB
A self-hosted alternative to TFC for state is the AWS combo:
- S3 stores the state file (versioned bucket, server-side encryption).
- DynamoDB holds a lock entry to prevent concurrent applies.
Trade-offs:
- TFC bundles state, locking, history, and run UI. S3+DynamoDB is just storage and locking — you still need a CI system to run Terraform.
- Recovery is easier with TFC (state versions are first-class in the UI). With S3 you rely on bucket versioning and have to download and restore manually.
- Audit trail is built into TFC; with S3+DynamoDB you stitch together CloudTrail and CD logs.
- Cost: S3+DynamoDB is pennies per workspace per month; TFC scales per managed resource and gets expensive past a few thousand resources.
A common path is to start with S3+DynamoDB for the early team, then migrate to TFC when run orchestration and policy become bottlenecks.