Terraform Cloud #
Everything discussed in the previous CI/CD articles — remote state, locking, plan approval, policy as code, drift detection — can be implemented yourself using GitHub Actions, S3, DynamoDB, and Checkov. But there’s no small effort involved in putting all of it together. Terraform Cloud (and Terraform Enterprise for on-premise) provides all these components as one integrated platform, with a UI designed specifically for the Terraform workflow. Understanding what it offers helps you decide when to build your own vs when to use Terraform Cloud.
What Terraform Cloud Offers #
TERRAFORM CLOUD — MAIN FEATURES:
STATE MANAGEMENT:
Remote state for all workspaces
Automatic locking
State history with rollback capability
Encryption at rest and in transit
REMOTE EXECUTION:
Plans and applies run in Terraform Cloud, not on local machines
Consistent environment for all executions
Logs stored and auditable
VCS INTEGRATION:
Connect to GitHub, GitLab, Bitbucket
Automatic plans when there's a PR/MR
Plan output shown as a check in the VCS
TEAM & ACCESS CONTROL:
RBAC (Role-Based Access Control) per workspace
Teams with granular permissions
Audit logs for all activity
POLICY (SENTINEL):
Policy as Code using the Sentinel language
Enforced across all workspaces
Soft-mandatory vs hard-mandatory policies
DRIFT DETECTION:
Scheduled health assessments
Workspace health dashboard
Setup: Using Terraform Cloud as a Backend #
# terraform.tf — Terraform Cloud backend configuration
terraform {
cloud {
organization = "my-company"
workspaces {
name = "production"
# Or use tags for multi-workspace:
# tags = ["production", "aws"]
}
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Log in to Terraform Cloud from the CLI
terraform login
# A browser will open to generate a token
# The token is stored in ~/.terraform.d/credentials.tfrc.json
# After logging in, terraform init will automatically use Terraform Cloud
terraform init
# terraform plan and apply now run in Terraform Cloud
# (not on your local machine)
terraform plan
# Output: Running plan in Terraform Cloud...
VCS Integration: Automatic Plans from PRs #
# No separate CI/CD configuration needed when using VCS integration
# Just connect the GitHub repository in the Terraform Cloud UI
# Workflow with VCS integration:
# 1. Developer opens a PR → Terraform Cloud automatically runs a plan
# 2. The plan output appears as a GitHub check on the PR
# 3. Reviewers see the plan directly in the PR
# 4. The PR is merged → Terraform Cloud automatically applies (if configured)
# or waits for manual confirmation in the Terraform Cloud UI
# Configuration in the Terraform Cloud workspace:
# - VCS Connection: github.com/myorg/infra-repo
# - Working Directory: infrastructure/environments/production
# - Terraform Version: 1.7.0
# - Apply Method: Manual apply (or Auto apply for non-production)
# - Auto Speculative Plans: Enabled
Remote Variables: Managing Configuration and Secrets #
Terraform Cloud stores variables centrally, including encrypted secrets.
VARIABLES IN TERRAFORM CLOUD:
Terraform Variables (HCL values):
environment = "production"
instance_count = 3
vpc_cidr = "10.2.0.0/16"
→ Stored as plaintext, appears in the plan output
Environment Variables (credentials and config):
AWS_ACCESS_KEY_ID = "..." [sensitive]
AWS_SECRET_ACCESS_KEY = "..." [sensitive]
TF_VAR_db_password = "..." [sensitive]
→ Encrypted, never appears in logs
Variable Sets:
Variable collections shareable across many workspaces
Example: "AWS Production Credentials" shared to all production workspaces
# Variables can be set via the CLI (useful for automation)
# Use the Terraform Cloud API or the tfe provider
# With the tfe provider:
resource "tfe_variable" "environment" {
key = "environment"
value = "production"
category = "terraform"
workspace_id = tfe_workspace.production.id
}
resource "tfe_variable" "aws_secret" {
key = "AWS_SECRET_ACCESS_KEY"
value = var.aws_secret_key
category = "env"
sensitive = true # Can't be read back after being set
workspace_id = tfe_workspace.production.id
}
Sentinel: Built-in Policy as Code #
Sentinel is the policy language integrated into Terraform Cloud (Plus packages and above). More powerful than Checkov for enterprise use cases because it runs inside the platform and can be enforced across all workspaces.
# policy/require-tags.sentinel
# All resources must have Environment and Owner tags
import "tfplan/v2" as tfplan
# Get all resources from the plan
all_resources = filter tfplan.resource_changes as _, rc {
rc.mode is "managed" and
rc.change.actions is not ["delete"]
}
# Check every resource has the required tags
required_tags = ["Environment", "Owner"]
violations = filter all_resources as address, rc {
tags = rc.change.after.tags else {}
any required_tags as tag {
not tags[tag]
}
}
# Main rule: there must be no violations
main = rule {
length(violations) is 0
}
SENTINEL POLICY TYPES:
advisory:
Violations are recorded but the apply can still proceed
→ Good for new rules still being socialized
soft-mandatory:
Violations block the apply, BUT can be overridden by authorized users
→ Good for rules that occasionally need exceptions
hard-mandatory:
Violations block the apply, CANNOT be overridden by anyone
→ Good for absolute compliance rules (HIPAA, PCI-DSS)
Terraform Cloud vs Self-Managed CI/CD #
TERRAFORM CLOUD SELF-MANAGED (GitHub Actions + S3)
──────────────────────────────────────────────────────────────────────────
Initial setup 30 minutes 2-4 hours (depending on complexity)
Maintenance Nearly zero Needs regular dependency updates
State management Built-in Needs S3 + DynamoDB setup
Locking Automatic Needs DynamoDB setup
Plan UI Great, integrated Depends on the implementation
Policy enforcement Sentinel (paid) Checkov/OPA (free, needs setup)
Audit logs Comprehensive Scattered across various places
Cost Paid (> 5 users) Free (but there's engineering cost)
Full control Limited Full
On-premise option Terraform Enterprise Possible (self-hosted runners)
WHEN TO CHOOSE TERRAFORM CLOUD:
✓ Small teams wanting a quick setup without much engineering overhead
✓ Budget already exists for tooling
✓ Sentinel is needed for strict compliance requirements
✓ The team lacks capacity to maintain its own CI/CD infrastructure
WHEN TO CHOOSE SELF-MANAGED:
✓ The team is already familiar with GitHub Actions or GitLab CI
✓ Limited budget or open-source preference
✓ Full control over pipeline behavior is needed
✓ A compliance requirement forbids data leaving to a third party
Terraform Cloud VCS Integration #
VCS WORKFLOW:
1. Developer pushes code to a branch
2. Terraform Cloud automatically detects the change
3. A plan is automatically run
4. Review the plan in the Terraform Cloud UI
5. Merge to main → Automatic apply (or needs approval)
flowchart LR
A["Push to\nbranch"] --> B["TFC auto\ndetects"]
B --> C["Auto\nplan"]
C --> D["Review\nin the UI"]
D --> E["Merge\nto main"]
E --> F["Auto\napply"]
style A fill:#e3f2fd,stroke:#1565c0
style F fill:#e8f5e9,stroke:#2e7d32Terraform Cloud Cost Estimation #
Terraform Cloud provides a cost estimation feature that’s very useful for pre-apply review.
COST ESTIMATION FEATURE:
├── Shows estimated cost per resource
├── Compares cost before and after the change
├── Supports AWS, GCP, Azure
├── Available in the plan output in the TFC UI
└── Can be integrated with policies (Sentinel)
flowchart LR
A["terraform plan\n(in TFC)"] --> B["Cost\nEstimation"]
B --> C["Estimate\nper resource"]
C --> D{"Budget\nexceeded?"}
D -->|"Yes"| E["Policy\ndenies apply"]
D -->|"No"| F["Allow\napply"]
style A fill:#e3f2fd,stroke:#1565c0
style E fill:#ffebee,stroke:#c62828
style F fill:#e8f5e9,stroke:#2e7d32Terraform Cloud Teams and RBAC #
TEAM STRUCTURE:
├── admins → Full access (plan + apply + settings)
├── developers → Plan only (apply needs approval)
└── viewers → Read only (view state and run history)
ROLE ASSIGNMENT:
# In the Terraform Cloud UI:
# Organization Settings → Teams → Add team
# Workspace Settings → Access → Set team permissions
Terraform Cloud Policy as Code #
# Sentinel Policy: Limit which resource types can be created
# policy/limit-resources.sentinel
import "tfplan/v2" as tfplan
allowed_resources = [
"aws_instance",
"aws_security_group",
"aws_vpc",
"aws_subnet",
"aws_s3_bucket",
]
main = rule {
all tfplan.resource_changes as _, rc {
rc.mode is "managed" and
rc.type in allowed_resources
}
}
# Policy sets in Terraform Cloud:
# Organization Settings → Policy Sets → Create
# Connect to the VCS repository containing the policy files
# Attach to workspace(s)
Terraform Cloud Private Registry #
TERRAFORM CLOUD PRIVATE REGISTRY:
Features:
├── Publish internal modules
├── Version management
├── Documentation hosting
├── Usage tracking
└── Policy enforcement
Benefits:
├── Single source of truth for modules
├── Consistent versioning
├── Discoverability
└── Access control
# Use a module from the private registry
module "networking" {
source = "app.terraform.io/my-org/networking/aws"
version = "~> 2.0"
vpc_cidr = "10.0.0.0/16"
environment = "production"
}
# Publish a module to the private registry
# 1. Connect the GitHub/GitLab repo
# 2. Tag with semver
# 3. Terraform Cloud auto-publishes
git tag -a v2.0.0 -m "Release 2.0.0"
git push origin v2.0.0
Terraform Cloud Cost Estimation #
TERRAFORM CLOUD COST ESTIMATION:
A built-in feature showing the estimated cost
of changes before applying.
Shows:
├── Resources increasing costs
├── Resources decreasing costs
├── Total estimated monthly cost change
└── Currency and provider info
Useful for:
├── Budget approval workflows
├── Cost awareness during reviews
└── Preventing unexpected cost spikes
# In the CLI: use infracost
# Install
brew install infracost/tap/infracost
# Register an API key
infracost auth login
# Generate a cost estimate
infracost breakdown --path .
# In CI/CD
infracost diff --path . --compare-to infracost-base.json
Summary #
- Terraform Cloud provides all Terraform CI/CD components in one platform: remote state, locking, VCS integration, plan UI, team access, policies, and drift detection.
- Setup is very fast — just add a
cloudblock interraform.tf, runterraform login, andterraform init. No S3, DynamoDB, or separate pipeline setup needed.- Remote Variables store configuration and secrets centrally, with built-in encryption for sensitive values.
- Sentinel is a more powerful policy engine than Checkov/OPA for enterprise use — it can be set as soft-mandatory (overridable) or hard-mandatory (not overridable).
- VCS Integration removes the need for a separate plan pipeline — Terraform Cloud automatically plans on PRs and shows the result as a GitHub check.
- Terraform Cloud suits teams wanting a quick setup without maintaining their own CI/CD infrastructure; self-managed suits teams needing full control or with specific constraints.
← Previous: Drift Detection Automation Next: Provider Authentication →