HCP Terraform Tutorial: CLI and Remote Runs

Tested on Ubuntu 26.04 LTS (Resolute Raccoon)
Package terraform 1.15.8-1
hashicorp/local 2.9.0
Applies to Any host with Terraform installed
Lab environment Single Ubuntu VM with Terraform and a free HCP Terraform account — Terraform lab environment on Ubuntu
Privilege Normal user
Scope Connecting the Terraform CLI to HCP Terraform for remote runs and remote state — authentication, the cloud block, initializing a CLI-driven workspace, remote plan and apply, execution modes, workflow types, and first-run troubleshooting. Does not cover project administration, variable sets, policies, or migrating an existing state file.
Related guides Terraform backends and remote state
Terraform state explained
terraform init
terraform apply
Terraform workspaces

Everything you have run so far kept two things on your own machine:

  • The state file that records what Terraform built
  • The process that runs plan and apply

That works until a second person needs to run terraform apply, or until you want an audit trail of who changed what. HCP Terraform moves both of those off your laptop while leaving the commands you type exactly as they are:

text
Ubuntu Terraform CLI
HCP Terraform workspace
        ├── remote state
        └── remote plan/apply environment

You still run terraform plan and terraform apply in a terminal. The work happens somewhere else, and the logs come back to you.

IMPORTANT
An HCP Terraform user API token carries the permissions of the user account that created it. Anyone who obtains the token can act with those permissions, and Terraform stores it in plain text on disk — so never commit it to Git, never paste it into an article or a chat, and never bake it into a container image. Revoke a token you suspect has leaked from the Tokens page in your user settings.

What HCP Terraform adds to the Terraform CLI

HCP Terraform is HashiCorp's hosted service for running Terraform. It is the same product that was called Terraform Cloud until the 2023 rename, which is worth knowing because plenty of documentation and Stack Overflow answers still use the old name. The hostname stayed app.terraform.io through the rename.

Terraform on its own is a binary that reads configuration and calls provider APIs. Everything around that binary — where state lives, who is allowed to apply, what happened last Tuesday — is left to you. HCP Terraform fills in that surrounding layer:

  • Managed state — state is stored, versioned, and locked for you, with no S3 bucket or DynamoDB table to build first
  • Remote runs — plan and apply execute on HCP Terraform's workers rather than on your machine
  • Workspaces — each workspace holds one state file, its own variables, and its own run history
  • Variables and secrets — workspace values are encrypted at rest and can be marked Sensitive so the stored value cannot be read back through the UI or the Variables API
  • Three ways to trigger a run — from the CLI, from a connected Git repository, or through the API
  • Governance — policy checks, cost estimation, and team permissions on the paid tiers

The Sensitive setting on a workspace variable is about storage, not run output:

  • Sensitive stops the stored value being read back through the UI or Variables API.
  • sensitive = true in configuration marks a variable or output for redaction in plan and apply output.
  • Treat output redaction as best-effort — a provider or unusual expression can still surface the value.

The free tier covers up to 500 managed resources per organization with unlimited users. This lab starts with the built-in terraform_data resource, which HashiCorp excludes from the managed-resource count, and later creates one local_file resource that does count — briefly, since everything is destroyed at the end.

What HCP Terraform does not change is the language or the command set:

  • Your .tf files stay the same.
  • terraform plan still means plan.
  • Plan output looks the same.

That is the whole point of the CLI-driven workflow: you get the managed pieces without learning a new tool.


Create an HCP Terraform account, organization, and workspace

Sign up for a free account at app.terraform.io and confirm the email that arrives. The confirmation link lands you on the Organizations page, where you create your first organization.

An organization is the billing and membership boundary. Inside it, projects group workspaces, and a workspace holds one state file:

text
Organization  (golinuxcloud-lab)
└── Project   (Default Project)
    └── Workspace  (hcp-terraform-tutorial)

Organization names are unique across all of HCP Terraform, so a personal lab name such as golinuxcloud-lab saves you from fighting over terraform-test. Every command below uses that name; substitute your own.

You do not need to create the workspace by hand. A workspace named in a cloud block is created automatically the first time you initialize, as a CLI-driven workspace with remote execution — which is exactly the shape this article wants. Creating it in the UI first also works if you:

  • Pick the CLI-driven workflow
  • Do not connect a Git repository yet

Before going further, check that your CLI is new enough. The cloud block needs Terraform 1.1 or later:

bash
terraform version

Sample output:

output
Terraform v1.15.8
on linux_amd64

Anything from 1.1 onward will work. Older releases have to use the remote backend instead, which is the predecessor of the cloud block.


Authenticate the Terraform CLI with terraform login

The CLI needs an API token before it can talk to your organization. The terraform login command handles the whole exchange:

bash
terraform login

It explains what it is about to do and waits for you to agree, because it is about to write a credential to disk:

output
Terraform will request an API token for app.terraform.io using your browser.

If login is successful, Terraform will store the token in plain text in
the following file for use by subsequent commands:
    /root/.terraform.d/credentials.tfrc.json

Do you want to proceed?
  Only 'yes' will be accepted to confirm.

  Enter a value: yes

---------------------------------------------------------------------------------

Terraform must now open a web browser to the tokens page for app.terraform.io.

If a browser does not open this automatically, open the following URL to proceed:
    https://app.terraform.io/app/settings/tokens?source=terraform-login

---------------------------------------------------------------------------------

Generate a token using your browser, and copy-paste it into this prompt.

Token for app.terraform.io:
  Enter a value:

Retrieved token for user golinuxcloud

   Welcome to HCP Terraform!

   Documentation: terraform.io/docs/cloud

On a desktop the browser opens by itself; on a headless VM you copy the printed URL. Click Generate token on that page, copy the value, and paste it at the prompt — nothing echoes back as you paste, which is expected. The Retrieved token for user line names the account the token belongs to, so read it as a confirmation that you authenticated as the right person.

The path in that message is the home directory of whoever ran the command, so yours will read /home/yourname/.terraform.d/ unless you are working as root the way this lab did. Terraform itself needs no elevated privileges here.

You can inspect the credentials file without exposing the secret by asking for the keys rather than the values:

bash
jq '.credentials | keys' ~/.terraform.d/credentials.tfrc.json

Sample output:

output
[
  "app.terraform.io"
]

One entry per host, which is what makes the same mechanism work for Terraform Enterprise: you run terraform login tfe.example.com and a second entry appears. Since the token sits there in clear text:

  • Keep the file out of any repository
  • Keep it out of dotfile sync tools that might expose it

For CI systems, writing a file into a home directory is awkward. Terraform also reads a token from an environment variable named after the host, with dots converted to underscores:

  • TF_TOKEN_app_terraform_io takes precedence over the credentials file
  • terraform logout removes the stored credential locally
  • Deleting the token under User settings → Tokens in the web UI revokes it everywhere

Connect your configuration with the cloud block

Work in a directory of its own so this exercise does not collide with your other labs:

bash
mkdir -p ~/terraform-labs/hcp-terraform-tutorial && cd ~/terraform-labs/hcp-terraform-tutorial

The cloud block is what turns an ordinary working directory into one that is bound to a workspace. Write a configuration with that block and a single built-in terraform_data resource, so nothing here needs a cloud provider account:

bash
cat > main.tf <<'EOF'
terraform {
  cloud {
    organization = "golinuxcloud-lab"

    workspaces {
      name = "hcp-terraform-tutorial"
    }
  }
}

variable "environment" {
  type        = string
  description = "Label applied to the demo resource"
  default     = "lab"
}

resource "terraform_data" "greeting" {
  input = "Hello from HCP Terraform (${var.environment})"
}

output "greeting" {
  value = terraform_data.greeting.output
}
EOF

Three things in that block decide where your run goes:

  • organization — names the organization you created
  • workspaces.name — binds this directory to exactly one workspace
  • workspaces.tags — alternative that maps one directory onto several workspaces (for example dev and prod)
  • hostname — optional; defaults to app.terraform.io and only needs setting for Terraform Enterprise

The cloud block replaces a backend block rather than joining it. A configuration cannot have both.

Now initialize. This is the step that contacts HCP Terraform, checks your token, and binds the directory to the workspace:

bash
terraform init

Sample output:

output
Initializing HCP Terraform...

Initializing provider plugins...
- terraform.io/builtin/terraform is built in to Terraform


HCP Terraform has been successfully initialized!

You may now begin working with HCP Terraform. Try running "terraform plan" to
see any changes that are required for your infrastructure.

The first line is the tell: an ordinary directory prints Initializing the backend... instead. The workspace did not exist a moment ago, and Terraform created it without asking. Confirm the CLI is pointed at it:

bash
terraform workspace list

Sample output:

output
* hcp-terraform-tutorial

The asterisk marks the current workspace, and the name is the remote one rather than the default you would see with local state. Reload the workspace list in the HCP Terraform UI and it appears there too, with no runs yet.


Run a remote plan and apply from the CLI

Nothing about the next command is new, which is the interesting part:

bash
terraform plan

Sample output:

output
Running plan in HCP Terraform. Output will stream here. Pressing Ctrl-C
will stop streaming the logs, but will not stop the plan running remotely.

Preparing the remote plan...

To view this run in a browser, visit:
https://app.terraform.io/app/golinuxcloud-lab/hcp-terraform-tutorial/runs/run-aHXb57jf6eqGpXQ6

Waiting for the plan to start...

Terraform v1.15.8
on linux_amd64
Initializing plugins and modules...

Terraform will perform the following actions:

  # terraform_data.greeting will be created
  + resource "terraform_data" "greeting" {
      + id     = (known after apply)
      + input  = "Hello from HCP Terraform (lab)"
      + output = (known after apply)
    }

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

Changes to Outputs:
  + greeting = (known after apply)

Read the top three lines carefully, because they describe something quite different from a local plan:

  • Terraform uploaded the contents of your directory and queued a run
  • Your terminal is now tailing the remote run logs
  • The second Terraform v1.15.8 banner is the remote worker introducing itself

The run URL is a permanent record you can open, share, or link from a ticket.

Because the run lives on the server, Ctrl-C only detaches your terminal. The plan keeps going, and you can watch the rest of it in the browser.

Applying works the same way, with the confirmation prompt still on your side of the connection:

bash
terraform apply

Sample output:

output
Running apply in HCP Terraform. Output will stream here.

To view this run in a browser, visit:
https://app.terraform.io/app/golinuxcloud-lab/hcp-terraform-tutorial/runs/run-RFgCegsVGGMdcAqs

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

Do you want to perform these actions in workspace "hcp-terraform-tutorial"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

terraform_data.greeting: Creating...
terraform_data.greeting: Creation complete after 0s [id=ce0bcf4b-7418-b9c8-abbd-223726987744]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

greeting = "Hello from HCP Terraform (lab)"

Note the wording of the prompt: it names the workspace you are about to change, not just the resources. That phrasing exists because a CLI-driven apply can affect infrastructure the rest of your team shares. Answering yes releases the run on the server, and the creation log streams back.

Outputs are stored with the state rather than on your disk, so reading one is a remote call:

bash
terraform output greeting

Sample output:

output
"Hello from HCP Terraform (lab)"

Open the workspace in the browser and the Runs tab now lists both operations:

  • A CLI terraform plan is recorded as a plan-only run
  • A CLI terraform apply is recorded as plan and apply

The history shows every speculative check as well as every real change.


Confirm that state now lives in HCP Terraform

The clearest evidence is what is missing from your working directory:

bash
ls -a

Sample output:

output
.
..
.terraform
main.tf

There is no terraform.tfstate and no backup file, even though you just created a resource. Yet Terraform still knows about that resource:

bash
terraform state list

Sample output:

output
terraform_data.greeting

That answer took a few seconds rather than being instant, because it came over the network. The .terraform directory holds only a pointer to the workspace — the state itself is on the server.

You can fetch the whole state document and look at its metadata:

bash
terraform state pull | jq '{terraform_version, serial, lineage}'

Sample output:

output
{
  "terraform_version": "1.15.8",
  "serial": 1,
  "lineage": "b3656a95-d714-f8d2-7233-37129e49669c"
}

The serial number increments on every state write, and HCP Terraform keeps each version rather than overwriting. The workspace's States tab lists them, so you can:

  • See which run produced which state version
  • Roll back if a change goes wrong

Run a second plan to be sure the recorded state matches reality:

bash
terraform plan

Sample output:

output
Running plan in HCP Terraform. Output will stream here.

To view this run in a browser, visit:
https://app.terraform.io/app/golinuxcloud-lab/hcp-terraform-tutorial/runs/run-Utf3331YjAnPxMVU

terraform_data.greeting: Refreshing state... [id=ce0bcf4b-7418-b9c8-abbd-223726987744]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.

No changes from a machine that holds no state file is the whole feature in one line. Any colleague who clones this configuration and runs terraform init gets the same answer, because they read the same state.


Remote execution, local execution, and the disposable run environment

Every workspace has an execution mode, and it decides which machine actually runs Terraform:

Execution mode Where plan and apply run What HCP Terraform provides How you recognize it
Remote (default) On HCP Terraform's workers State, run history, variables, logs, policy checks Output starts with Running plan in HCP Terraform and prints a run URL
Local On your own machine State storage and locking only No run URL; you see Acquiring state lock instead

Remote is the default and the mode everything above used. The property that surprises people is that the remote run environment is disposable:

  • It is created for one run
  • It is thrown away afterwards
  • Anything a run writes to its own filesystem goes with it

That is easiest to believe once you watch it happen. Rewrite the configuration with a local_file resource, which writes a file next to your configuration, and declare the provider it comes from:

bash
cat > main.tf <<'EOF'
terraform {
  cloud {
    organization = "golinuxcloud-lab"

    workspaces {
      name = "hcp-terraform-tutorial"
    }
  }

  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "~> 2.5"
    }
  }
}

variable "environment" {
  type        = string
  description = "Label applied to the demo resource"
  default     = "lab"
}

resource "terraform_data" "greeting" {
  input = "Hello from HCP Terraform (${var.environment})"
}

resource "local_file" "note" {
  filename = "${path.module}/generated/hello.txt"
  content  = "Written during the run\n"
}

output "greeting" {
  value = terraform_data.greeting.output
}
EOF

local_file comes from a real provider rather than being built in, so the working directory needs the plugin before the next run:

bash
terraform init

Sample output:

output
Initializing HCP Terraform...

Initializing provider plugins...
- terraform.io/builtin/terraform is built in to Terraform
- Finding hashicorp/local versions matching "~> 2.5"...
- Installing hashicorp/local v2.9.0...
- Installed hashicorp/local v2.9.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above.

HCP Terraform has been successfully initialized!

Terraform installed the provider locally so it can parse and validate your configuration. The remote worker downloads its own copy when the run starts. Apply the addition:

bash
terraform apply

Sample output:

output
# local_file.note will be created
  + resource "local_file" "note" {
      + content              = <<-EOT
            Written during the run
        EOT
      + filename             = "./generated/hello.txt"
      + id                   = (known after apply)
    }

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

  Enter a value: yes

local_file.note: Creating...
local_file.note: Creation complete after 0s [id=e954becebab751d8ee58496db9c2cbe7795d1a73]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Terraform reports that it created the file. Look for it where the configuration said it would go:

bash
ls -l generated/hello.txt

Sample output:

output
ls: cannot access 'generated/hello.txt': No such file or directory

The file was real, and it was created — inside the run environment, which no longer exists. This is the single most common surprise when a working local configuration is moved to HCP Terraform. Rethink configurations that:

  • Read or write local paths
  • Shell out to scripts on disk
  • Expect an SSH key or other file in your home directory

The run happens on a machine you never see.

Switching the workspace to local execution makes the contrast obvious. In the UI, open Settings → General, choose Local under Execution Mode, and save. Then plan again:

bash
terraform plan

Sample output:

output
Acquiring state lock. This may take a few moments...
terraform_data.greeting: Refreshing state... [id=ce0bcf4b-7418-b9c8-abbd-223726987744]
local_file.note: Refreshing state... [id=e954becebab751d8ee58496db9c2cbe7795d1a73]

  # local_file.note will be created
  + resource "local_file" "note" {
      + filename             = "./generated/hello.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.
Releasing state lock. This may take a few moments...

Two details changed:

  • There is no run URL and no streaming banner — your own machine did the work
  • You see state lock messages — HCP Terraform still holds the state

That is local execution in one transcript: the CLI executes, the service stores.

The plan itself makes the disposable filesystem point a second time. The local_file provider checks whether the file exists during refresh, finds nothing, and concludes the resource was deleted — so Terraform offers to create it again. Under remote execution that would happen on every single run, forever, because each run starts with an empty disk.

Set the execution mode back to Remote in the same settings page before continuing.


CLI-driven, VCS-driven, and API-driven workflows

The workspace you built is CLI-driven, which is one of three ways HCP Terraform can start a run:

Workflow What triggers a run Where the configuration comes from Typical use
CLI-driven terraform plan or terraform apply on your machine, on a workspace with no linked repository Uploaded from your working directory Learning, day-to-day development, teams not ready to gate on Git
VCS-driven A commit or pull request in a connected repository Cloned by HCP Terraform from the repo Production pipelines where every change is reviewed and merged
API-driven An HTTP call that uploads a configuration and queues a run Uploaded by your own tooling Custom pipelines and platform teams building on top of Terraform

These workflows overlap for speculative planning, but not for applying:

  • A VCS-connected workspace still accepts terraform plan from the CLI against your local configuration — handy before you commit
  • CLI-driven remote terraform apply is only available on workspaces with no linked VCS repository
  • Once a workspace is connected to a repository, real changes must come through the VCS workflow — the repository is the source of truth

Every workflow ends up in the same run history against the same state.

Pick CLI-driven while you are learning:

  • Keeps the feedback loop short
  • Matches the certification exam workflow for Terraform CLI integration
  • Does not require a Git repository before you can see a run

Common HCP Terraform CLI problems

The failures below are the ones that stop a first run, and each has a message specific enough to identify it.

An invalid or expired token fails during init, before Terraform looks at anything else:

bash
terraform init

Sample output:

output
Error: Failed to read organization "golinuxcloud-lab" at host app.terraform.io

  on main.tf line 3, in terraform:
   3:     organization = "golinuxcloud-lab"

Encountered an unexpected error while reading the organization settings:
unauthorized

The heading points at your organization line, which sends people off checking a name that is perfectly correct. The word that matters is unauthorized on the last line — the credential was rejected. Run terraform login again, or check whether a stale TF_TOKEN_app_terraform_io in your shell is overriding the credentials file.

A misspelled organization produces an almost identical heading with a very different ending:

bash
terraform init

Sample output:

output
Error: Failed to read organization "golinuxcloud-labs" at host app.terraform.io

Encountered an unexpected error while reading the organization settings:
organization "golinuxcloud-labs" at host app.terraform.io not found.

Please ensure that the organization and hostname are correct and that your
API token for app.terraform.io is valid.

not found rather than unauthorized means the token was accepted and the name was wrong. Compare the string against the organization name in the URL when you are signed in to the UI — a trailing s is enough to break it.

When init fails on the organization line, read the last line of the error:

  • unauthorized — token problem
  • not found — organization name problem

Editing the cloud block after a directory is initialized stops the next command immediately:

bash
terraform plan

Sample output:

output
Error: HCP Terraform or Terraform Enterprise initialization required: please run "terraform init"

Reason: HCP Terraform configuration block has changed.

Changes to the HCP Terraform configuration block require reinitialization,
to discover any changes to the available workspaces.

To re-initialize, run:
  terraform init

Terraform refuses to guess whether you meant to switch workspaces or made a typo. Re-run terraform init, and add -reconfigure when you want to discard the existing binding rather than carry it over.

The last common one only happens remotely. A variable with no default fails the run instead of prompting, because the worker has no terminal to prompt with:

bash
terraform plan

Sample output:

output
Error: No value for required variable

  on main.tf line 11:
  11: variable "owner" {

The root module input variable "owner" is not set, and has no default
value. Use a -var or -var-file command line argument to provide a value for
this variable.

The suggested fix is written for local runs. With the CLI-driven workflow the natural home for the value is the workspace itself: open the Variables tab, add owner as a Terraform variable, and run again. Passing -var on the command line also works, and a terraform.tfvars file in the directory is uploaded along with everything else.

A few more that are quicker to recognize than to reproduce:

Symptom Likely cause Fix
Run fails reaching a provider API or private registry The HCP Terraform worker has no route to a host that your laptop can reach Switch the workspace to local execution, or use an HCP Terraform agent inside your network
Plan succeeds locally but the run never appears in the UI Workspace is in local execution mode Set Execution Mode back to Remote under Settings → General
Provider authentication fails only on remote runs Credentials come from environment variables on your machine, which the worker never sees Add them as environment variables on the workspace and mark them sensitive
Configuration reads or writes local files, or shells out to scripts The run environment is disposable and starts empty Redesign around remote-friendly resources, or run that workspace in local execution mode
terraform apply is rejected after a successful plan Your team role does not include apply permission on that workspace Ask an owner for apply access, or approve the run in the UI

Clean up the lab

Nothing here costs money, but the local_file resource does count against your organization's managed resource total for as long as it exists, and a stale workspace is clutter. Destroy the lab the same way you would anything else:

bash
terraform destroy

Sample output:

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

Do you really want to destroy all resources in workspace "hcp-terraform-tutorial"?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

terraform_data.greeting: Destroying... [id=ce0bcf4b-7418-b9c8-abbd-223726987744]
terraform_data.greeting: Destruction complete after 0s

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.

Only one resource was destroyed even though two were applied, and that is the disposable filesystem again — the refresh at the start of the destroy found no file on the fresh worker, dropped local_file.note from state, and left terraform_data.greeting as the only thing to remove. Confirm nothing is left:

bash
terraform state list

The command prints nothing at all when the state is empty, which is the result you want. The workspace itself still exists; delete it from Settings → Destruction and Deletion in the UI if you do not plan to reuse it.

Finally, remove the stored credential from the machine:

bash
terraform logout

Sample output:

output
Removing the stored credentials for app.terraform.io from the following file:
    /root/.terraform.d/credentials.tfrc.json

Success! Terraform has removed the stored API token for app.terraform.io.

Read that message precisely: it removed the stored token, which is the local copy. The token itself is still valid on the server, so if the machine was shared or temporary, delete the token under User settings → Tokens in the UI as well.


References


Summary

You connected a local Terraform CLI to HCP Terraform and ran the ordinary workflow against it. Three pieces did the work:

  • terraform login — stored an API token on disk
  • cloud block — named your organization and workspace
  • terraform init — bound the directory and created the workspace on the spot

From there, terraform plan and terraform apply behaved as always, except each one:

  • Queued a run on HCP Terraform workers
  • Streamed logs back to your terminal
  • Printed a URL to a permanent run record

The terraform_data resource kept the exercise free of cloud credentials.

The change worth internalizing is where things now live:

  • Your working directory has no state file
  • terraform state list and terraform output are network calls against shared remote state
  • The remote run environment is disposablelocal_file reported success but left nothing on disk
  • Configurations that touch the local filesystem, read shell environment variables, or expect an SSH agent need rethinking — or the workspace needs local execution mode

When a first run fails, read past the error heading to the last line:

  • unauthorized — token problem
  • not found — organization name problem
  • A variable with no default fails outright on remote runs — set it in the workspace Variables tab

From here, the natural next steps are:

  • Organizing workspaces into projects
  • Moving variables and provider credentials into the workspace for remote authentication
  • Bringing an existing local terraform.tfstate under HCP Terraform management

All three build on the connection you just made.


Frequently Asked Questions

1. Is HCP Terraform the same thing as Terraform Cloud?

Yes. HCP Terraform is the current name for the hosted service that HashiCorp used to call Terraform Cloud, and the rename happened in 2023 when the service moved under the HashiCorp Cloud Platform brand. The hostname app.terraform.io did not change, the API did not change, and older tutorials that mention Terraform Cloud describe the same product. Terraform Enterprise is the self-hosted edition and uses the same cloud block with a different hostname.

2. Where does terraform login store the API token?

It writes the token in plain text to credentials.tfrc.json inside the .terraform.d directory in your home folder. Terraform tells you the exact path before it asks you to confirm, so you always know what is about to be written. Because the file is not encrypted, keep it out of any Git repository and treat it like an SSH private key. You can also supply the token through a TF_TOKEN_app_terraform_io environment variable instead, which is the usual choice for CI systems where writing a file to a home directory makes no sense.

3. Do I need an AWS, Azure, or GCP account to try HCP Terraform?

No. The connection between the Terraform CLI and HCP Terraform is independent of which providers your configuration uses, so you can learn the whole workflow with the built-in terraform_data resource and never authenticate to a cloud vendor. That keeps the exercise free and removes the risk of leaving billable infrastructure behind. You only need provider credentials once you start managing real infrastructure, and at that point they go into the workspace as environment variables rather than onto your laptop.

4. What is the difference between remote and local execution mode?

In remote execution mode HCP Terraform runs the plan and apply on its own workers and streams the logs back to your terminal, so the operation happens on infrastructure you do not control and each run prints a link to its record in the web UI. In local execution mode your own machine runs the operation and HCP Terraform only stores state, which makes it behave much like an ordinary remote backend. You can tell the two apart without checking settings, because a remote run prints a run URL while a local run prints state lock messages instead.

5. Why does my remote run fail with No value for required variable?

A remote run has no terminal to prompt you with, so any variable that has no default and no value configured anywhere fails the run instead of asking for input the way a local run would. Terraform variables live in the workspace when you use the CLI-driven workflow, so set the value under the workspace Variables tab as a Terraform variable. Passing the value on the command line with -var also works for a one-off run, and a terraform.tfvars file committed alongside your configuration is uploaded with the rest of the directory.

6. Do terraform state commands still work once state is in HCP Terraform?

They do. Commands such as terraform state list, terraform state show, and terraform state pull read straight from the remote state that HCP Terraform holds, so you keep the same inspection workflow you used with a local state file. The difference is that each command makes a network call and takes a few seconds instead of reading a file from disk. Writes such as terraform state rm also work, and HCP Terraform records a new state version each time so you can see the history in the web UI.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)