HCP Terraform: Workspaces, Variable Sets, Remote Runs & Migration

What HCP Terraform Actually Solves

Terraform OSS is a CLI tool. Works great for one person. The moment you have a team, the cracks show:

  • State lives on someone’s laptop. That person goes on vacation. Good luck.
  • Plans and applies run from whoever has the right environment variables set up — “it works on Sarah’s machine” is not a deployment strategy.
  • Variables and secrets get emailed around in .tfvars files. Someone commits one to Git. Security sends a strongly worded Slack message.
  • Nobody can tell you who applied what, when, or what changed. Audit asks. You shrug.

HCP Terraform (formerly Terraform Cloud) is HashiCorp’s hosted platform that solves all of this. Central state, remote execution, variable management, audit logs. It’s the difference between running infrastructure like a hobby project and running it like a business.

Connecting to HCP Terraform

Login:

terraform login
# Opens browser for authentication, saves token to ~/.terraform.d/credentials.tfrc.json

The cloud Block:

Replace your backend configuration with the cloud block:

terraform {
  cloud {
    organization = "my-company"

    workspaces {
      name = "prod-networking"
    }
  }
}

Run terraform init — Terraform authenticates to HCP, connects to the workspace, and migrates state if you had an existing backend.

One thing to know: the cloud block and the backend block are mutually exclusive. Pick one. You’ll get a clear error if you try to use both, but it’s better to know upfront.

HCP Terraform Workspaces

In HCP Terraform, a workspace isn’t just an isolated state file. It’s a full execution environment:

  • State storage — encrypted, versioned, with audit history
  • Variable storage — workspace-specific or shared via variable sets
  • Run history — every plan and apply ever run, including who triggered them
  • Team access control — who can plan, who can apply, who can read
  • VCS integration — connect to GitHub/GitLab, auto-trigger plans on commits

Three workspace types by execution model:

TypeHow runs happen
VCS-drivenPlans triggered by commits/PRs to connected repo
CLI-driventerraform apply from local CLI, executes remotely
API-drivenPlans/applies triggered via HCP Terraform API

Most teams start with CLI-driven (familiar workflow, just remote execution) and graduate to VCS-driven (full GitOps) once they’re comfortable.

VCS-Driven Workflow

This is the GitOps model for infrastructure:

  1. Connect HCP Terraform workspace to a GitHub repo
  2. When a PR is opened → HCP Terraform runs terraform plan automatically
  3. Plan output is posted as a PR comment or check
  4. When merged to main → auto-apply runs terraform apply

Infrastructure changes go through the exact same code review process as application changes. No special permissions needed. No “can you run this on your machine?” conversations.

CLI-Driven Workflow

Your CLI sends the config to HCP Terraform, which runs the plan/apply remotely:

terraform plan   # Runs in HCP Terraform's infrastructure, output streams to your CLI
terraform apply  # Runs remotely, streams output, saves state remotely

All state is stored in HCP Terraform. No local state file. Your laptop is just a thin client sending commands. This means your laptop doesn’t need cloud credentials — HCP Terraform has them. That alone is a significant security improvement.

Variable Sets

This is one of those features that sounds simple but changes how you operate. Variable sets are groups of variables that can be applied to multiple workspaces at once.

Classic use case: Cloud credentials.

Create a variable set “AWS Prod Credentials”:

  • AWS_ACCESS_KEY_ID = AKIA... (environment variable, sensitive)
  • AWS_SECRET_ACCESS_KEY = wJalrX... (environment variable, sensitive)

Apply this variable set to 10 workspaces. All 10 get those credentials automatically. Need to rotate the key? Change it once. All 10 workspaces immediately get the new value. No touching individual workspace configs.

Types of variables in HCP Terraform:

TypeWhat it maps to
Terraform variablevar.<name> in config
Environment variableShell environment (TF_VAR_, AWS_*, etc.)

Mark a variable as sensitive in the UI and HCP Terraform will never show the value again after entry. Still available to runs, just hidden from eyeballs.

Migrating State to HCP Terraform

Moving from a local or S3 backend to HCP Terraform is surprisingly smooth:

  1. Add the cloud block to your config
  2. Run terraform init
  3. Terraform detects existing state and asks to migrate
  4. Type yes — state is migrated
$ terraform init

Initializing Terraform Cloud...

There are some resources that need to be migrated to Terraform Cloud
before init can be completed. The following workspaces contain resources:

- default

Do you wish to proceed? (y/n) yes

Successfully migrated state to Terraform Cloud!

From this point, state lives in HCP Terraform. You can delete the local state file. I’ve done this migration dozens of times across multiple orgs and it’s been smooth every time.

Upgrading Terraform Version in HCP

Each HCP Terraform workspace has a configured Terraform version. Set it in workspace settings.

Pin the version in both the required_version constraint AND the workspace setting. They should match:

terraform {
  required_version = "~> 1.7"

  cloud {
    organization = "my-company"
    workspaces { name = "prod" }
  }
}

HCP Terraform respects required_version. If the workspace is set to run 1.5 but your config requires >= 1.7, the run fails immediately with a clear message. Better than silently running on an incompatible version and getting weird plan output.

Run Triggers

Configure a workspace to automatically trigger when another workspace’s state changes:

networking-prod workspace applies → triggers compute-prod workspace to plan

Declarative infrastructure pipelines. When the network team changes a subnet, the compute workspace automatically re-plans to check if the changes affect it. If the plan shows changes, it goes through the normal approval flow.

Set this in the HCP Terraform UI under workspace settings → Run Triggers.

terraform login and Token Management
# Authenticate to HCP Terraform
terraform login

# Authenticate to a private Terraform Enterprise instance
terraform login https://tfe.company.com

# Token is stored at:
cat ~/.terraform.d/credentials.tfrc.json

That token has the same permissions as the user or team token used to generate it. Treat it like a password. If it shows up in a log or a Git commit, rotate it immediately.

Key Takeaways

In CLI-driven mode, terraform apply executes remotely but streams output to your terminal. Your local machine doesn’t need cloud credentials at all — HCP Terraform runs the apply using credentials configured in the workspace. This matters a lot from a security standpoint. No more AWS access keys on developer laptops.

When using HCP Terraform, terraform.tfstate is NOT created locally. All state is remote. If you need to inspect state locally for debugging, pull a copy: terraform state pull > local-copy.tfstate.

Variable sets are the answer for credentials shared across workspaces. Don’t configure AWS/GCP credentials individually in each workspace — one variable set, applied to all relevant workspaces. When you need to rotate credentials (and you will), you do it in one place.