TerraformPilot

Terraform

Terraform Cloud Workspaces - Remote State and Collaboration

Use Terraform Cloud workspaces for remote state, team collaboration, and policy enforcement. VCS integration, variable sets, run triggers, and Sentinel...

LLuca Berton1 min read

Quick Answer

#
terraform {
  cloud {
    organization = "my-org"
    workspaces {
      name = "my-app-production"
    }
  }
}
terraform login  # Authenticate with Terraform Cloud
terraform init
terraform plan
terraform apply

Organization Setup

#
# Manage Terraform Cloud with Terraform
provider "tfe" {
  hostname = "app.terraform.io"
}
 
resource "tfe_organization" "main" {
  name  = "my-company"
  email = "admin@example.com"
}
 
resource "tfe_project" "infra" {
  organization = tfe_organization.main.name
  name         = "infrastructure"
}

Workspace Configuration

#
resource "tfe_workspace" "production" {
  name         = "my-app-production"
  organization = tfe_organization.main.name
  project_id   = tfe_project.infra.id
 
  # VCS integration
  vcs_repo {
    identifier     = "myorg/infrastructure"
    branch         = "main"
    oauth_token_id = tfe_oauth_client.github.oauth_token_id
  }
 
  working_directory    = "environments/production"
  terraform_version    = "1.8.5"
  auto_apply           = false         # Require manual approval
  queue_all_runs       = false
  speculative_enabled  = true          # Plan on PRs
  file_triggers_enabled = true
  trigger_prefixes     = ["modules/"]  # Also trigger on module changes
 
  tag_names = ["production", "aws"]
}
 
resource "tfe_workspace" "staging" {
  name         = "my-app-staging"
  organization = tfe_organization.main.name
  project_id   = tfe_project.infra.id
 
  vcs_repo {
    identifier     = "myorg/infrastructure"
    branch         = "main"
    oauth_token_id = tfe_oauth_client.github.oauth_token_id
  }
 
  working_directory   = "environments/staging"
  terraform_version   = "1.8.5"
  auto_apply          = true           # Auto-apply in staging
}

Variables

#
# Workspace variables
resource "tfe_variable" "aws_region" {
  key          = "aws_region"
  value        = "us-east-1"
  category     = "terraform"  # terraform or env
  workspace_id = tfe_workspace.production.id
}
 
resource "tfe_variable" "aws_access_key" {
  key          = "AWS_ACCESS_KEY_ID"
  value        = var.aws_access_key
  category     = "env"
  sensitive    = true
  workspace_id = tfe_workspace.production.id
}
 
# Variable sets (shared across workspaces)
resource "tfe_variable_set" "aws_creds" {
  name         = "AWS Credentials"
  organization = tfe_organization.main.name
}
 
resource "tfe_variable" "shared_aws_key" {
  key             = "AWS_ACCESS_KEY_ID"
  value           = var.aws_access_key
  category        = "env"
  sensitive       = true
  variable_set_id = tfe_variable_set.aws_creds.id
}
 
resource "tfe_workspace_variable_set" "production" {
  workspace_id    = tfe_workspace.production.id
  variable_set_id = tfe_variable_set.aws_creds.id
}

Run Triggers (Pipeline)

#
# When networking workspace applies, trigger compute workspace
resource "tfe_run_trigger" "compute" {
  workspace_id  = tfe_workspace.compute.id
  sourceable_id = tfe_workspace.networking.id
}

Remote State Sharing

#
# In networking workspace
output "vpc_id" {
  value = aws_vpc.main.id
}
 
# In compute workspace
data "tfe_outputs" "networking" {
  organization = "my-company"
  workspace    = "networking-production"
}
 
resource "aws_instance" "web" {
  subnet_id = data.tfe_outputs.networking.values.subnet_id
}

Teams and Permissions

#
resource "tfe_team" "developers" {
  name         = "developers"
  organization = tfe_organization.main.name
}
 
resource "tfe_team_access" "dev_staging" {
  access       = "write"    # read, plan, write, admin
  team_id      = tfe_team.developers.id
  workspace_id = tfe_workspace.staging.id
}
 
resource "tfe_team_access" "dev_prod" {
  access       = "plan"     # Devs can plan but not apply to prod
  team_id      = tfe_team.developers.id
  workspace_id = tfe_workspace.production.id
}

CLI vs VCS Workflow

#
FeatureCLI-DrivenVCS-Driven
Triggerterraform applyGit push/merge
Plan on PRNoYes (speculative)
Best forDevelopment, migrationProduction CI/CD
Auto-applyOptionalOptional
Working directoryLocalFrom repo

Free vs Paid

#
FeatureFreeTeamBusiness
State management
Remote plans
Users5UnlimitedUnlimited
Sentinel policies
SSO
Audit logging
Run tasks1UnlimitedUnlimited
#

Conclusion

#

Terraform Cloud replaces S3/GCS backends with managed state, adds team permissions, VCS-driven workflows, and run triggers for workspace pipelines. Start with CLI-driven for migration, switch to VCS-driven for production. Use variable sets for shared credentials across workspaces.

#Terraform#HashiCorp#Terraform Cloud#DevOps#Infrastructure as Code

Share this article