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
.tfvarsfiles. 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:
| Type | How runs happen |
|---|---|
| VCS-driven | Plans triggered by commits/PRs to connected repo |
| CLI-driven | terraform apply from local CLI, executes remotely |
| API-driven | Plans/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:
- Connect HCP Terraform workspace to a GitHub repo
- When a PR is opened → HCP Terraform runs
terraform planautomatically - Plan output is posted as a PR comment or check
- 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:
| Type | What it maps to |
|---|---|
| Terraform variable | var.<name> in config |
| Environment variable | Shell 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:
- Add the
cloudblock to your config - Run
terraform init - Terraform detects existing state and asks to migrate
- 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.

