| name | tfc-api |
| description | Query Terraform Cloud (TFC) workspaces, runs, plans, logs, and team/project access via API. Use when inspecting TFC workspace state, checking run history, analyzing plan output, reviewing apply logs, managing team permissions, or diagnosing access issues in a Terraform Cloud organization. |
Terraform Cloud API
CRITICAL DIRECTIVE: Always prefer using the terrapyne CLI (e.g. uv run terrapyne or tfc) for TFC operations. Only fall back to raw API calls (curl/httpie) or the bash scripts listed below if terrapyne is not available in the environment or lacks the required functionality.
Example: Instead of ./scripts/list-runs.sh, use uv run terrapyne run list. Instead of manual curl for workspace discovery, use uv run terrapyne workspace list or tfc project find.
Query TFC workspaces, runs, logs, and team permissions without leaving the terminal.
Authentication
All scripts use a two-tier token resolution: TFC_TOKEN env var takes precedence, falling back to ~/.terraform.d/credentials.tfrc.json. This matters because personal tokens often lack org-level permissions (e.g. team management) that automation tokens have.
export TFC_TOKEN=<your-token>
source /tmp/env.sh
Gotcha: A personal token may return 404 or empty results for team/project
operations that an automation token can see. If find-team.sh returns no
results but you know teams exist, try an elevated token.
Team & Project Access (permissions management)
Read the reference first: references/tfc-team-project-access.md
Key gotchas:
- Teams API supports
q= search — always use it (large orgs may have 1000+ teams)
- Projects API does NOT support
q= — must paginate manually via find-project.sh
tfe_team_project_access with access=admin in Terraform ≠ guaranteed admin in TFC API — always verify
workspace_access.runs = "read" = users are blocked; must be "apply" for full access
./scripts/find-team.sh {ORGANIZATION} <name_pattern>
./scripts/find-project.sh {ORGANIZATION} <name_pattern>
./scripts/get-team-project-access.sh <project_id> <team_id>
./scripts/compare-team-project-access.sh <proj_a> <team_a> \
<proj_b> <team_b>
./scripts/set-team-project-access.sh <project_id> <team_id> admin
Workspace Discovery
Prefer terrapyne:
tfc workspace list
tfc workspace show
tfc project find <pattern>
Script/curl fallback (when terrapyne unavailable or lacks feature):
BASE="https://app.terraform.io/api/v2"
curl -s -H "Authorization: Bearer $TFC_TOKEN" \
"$BASE/organizations/{ORGANIZATION}/workspaces?search[name]=<pattern>" \
| jq '.data[] | {id, name: .attributes.name}'
curl -s -H "Authorization: Bearer $TFC_TOKEN" \
"$BASE/organizations/{ORGANIZATION}/workspaces?search%5Bwildcard-name%5D=*<pattern>*" \
| jq '.data[] | {id, name: .attributes.name}'
http GET "$BASE/organizations/{ORGANIZATION}/workspaces" \
"Authorization: Bearer $TFC_TOKEN" \
"search[wildcard-name]==*<pattern>*" \
| jq '.data[] | {id, name: .attributes.name}'
curl -s -H "Authorization: Bearer $TFC_TOKEN"
"$BASE/organizations/{ORGANIZATION}/workspaces/"
| jq '{id: .data.id, name: .data.attributes.name}'
## Run Management
**Prefer terrapyne:**
```bash
tfc run list -w <workspace-name>
tfc run trigger <workspace-name> -m "message" --wait
tfc run watch <run-id>
tfc run apply <run-id> -m "Approving"
tfc run logs <run-id> --stage plan
tfc run logs <run-id> --stage apply
tfc run discard <run-id> -m "reason"
Script fallback (when terrapyne unavailable or lacks feature):
./scripts/list-runs.sh {ORGANIZATION} <workspace-name>
./scripts/trigger-run.sh {ORGANIZATION} <workspace-name> false "message"
./scripts/wait-for-run.sh <run-id>
./scripts/apply-run.sh <run-id> "Approving"
Unlocking a workspace blocked by old runs
Prefer terrapyne where possible:
tfc run discard <run-id> -m "Discarding to re-plan"
Curl fallback:
TFC_TOKEN=$(jq -r '.credentials."app.terraform.io".token' ~/.terraform.d/credentials.tfrc.json)
BASE="https://app.terraform.io/api/v2"
curl -s -X POST -H "Authorization: Bearer $TFC_TOKEN" \
-H "Content-Type: application/vnd.api+json" \
-d '{"comment":"Discarding to re-plan"}' \
"$BASE/runs/<run-id>/actions/discard"
curl -s -X POST -H "Authorization: Bearer $TFC_TOKEN" \
-H "Content-Type: application/vnd.api+json" \
-d '{"comment":"Cancelling"}' \
"$BASE/runs/<run-id>/actions/cancel"
Gotcha: If the workspace is locked by run A and run B is queued behind it,
you must discard/cancel A first — B won't start until A releases the lock.
Check locked-by on the workspace to find the blocking run:
curl -s -H "Authorization: Bearer $TFC_TOKEN" \
"$BASE/organizations/{ORG}/workspaces/<name>" \
| jq '.data.relationships["locked-by"].data.id'
Switching VCS branch for speculative plans
Note: terrapyne does not yet have a workspace set-branch command (tracked as F13). Use the script fallback:
./scripts/set-workspace-branch.sh {ORGANIZATION} <workspace-name> <branch>
Useful for testing a consolidated branch (iac-reveng) against workspaces
that normally point at per-env branches (iac-reveng-dev). Remember to
reset the branch after validation.
Workspace State Inspection
Prefer terrapyne:
tfc run logs <run-id> --stage plan
tfc run logs <run-id> --stage apply
Script fallback:
./scripts/get-plan.sh <run-id>
./scripts/get-apply.sh <run-id>
Helper Scripts
| Script | Purpose |
|---|
find-workspace.sh | Find workspaces by name or wildcard pattern (prefix/suffix/substring) |
find-team.sh | Find teams by name pattern using q= (handles 1000+ teams) |
find-project.sh | Find projects by name fragment (paginates all pages) |
list-team-project-access.sh | List all team access entries for a project |
get-team-project-access.sh | Get one team's access record for a project |
compare-team-project-access.sh | Diff permissions between two teams |
set-team-project-access.sh | Update team access level on a project |
list-runs.sh | List recent runs for a workspace |
trigger-run.sh | Trigger a new run (supports destroy) |
apply-run.sh | Confirm/apply a planned run |
wait-for-run.sh | Poll status until terminal state |
get-plan.sh | Download and parse plan logs |
get-apply.sh | Download and parse apply logs |
get-workspace-info.sh | Detect ORG and Workspace from local TF config |
set-workspace-branch.sh | Update VCS branch for speculative plans |
open-workspace.sh | Open TFC workspace in browser |
publish-registry-module-vcs.sh | Publish a registry module via VCS |
check-registry-module-status.sh | Check registry module status |
delete-registry-module.sh | Delete a registry module |
References
references/tfc-team-project-access.md — Team permissions CRUD, pagination gotchas, access level semantics
references/tfc-api-reference.md — Workspace/run/plan/log operations
references/tfc-vcs-validation.md — VCS configuration validation
- TFC API Docs