About tfc-run-status
tfc-run-status is a skill for checking the status and details of a known Terraform Cloud run. It helps infrastructure teams track progress, review resource-change counts and cost estimates, and see which actions are available.
Key features
- 01Run status and timestamp checks
- 02Resource change counts
- 03Available action and permission checks
- 04Cost estimate retrieval
- 05Polling until a final state
Use cases
- 01Checking whether a run completed successfully
- 02Monitoring a run until it finishes
- 03Reviewing change counts and available actions
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ laurigates/ claude-plugins --skill tfc-run-statusAfter installing, type/tfc-run-statusin Claude Code to confirm it loaded.
Details
From the project READMETerraform Cloud Run Status
Quick status check for Terraform Cloud runs with resource change counts, timestamps, and available actions.
When to Use This Skill
| Use this skill when... | Use a sibling instead when... |
|---|---|
| Checking whether a known run ID succeeded, failed, or is mid-flight | Reading the full plan/apply log text (tfc-run-logs) |
| Polling a run until it reaches a final state | Analyzing structured plan JSON for resource changes (tfc-plan-json) |
| Inspecting available actions (confirm/cancel/discard) on a run | Listing or filtering many runs to discover an ID (tfc-list-runs) |
| Reading cost estimate or resource add/change/destroy counts | Browsing latest runs for FVH workspaces (tfc-workspace-runs) |
Prerequisites
export TFE_TOKEN="your-api-token" # User or team token
export TFE_ADDRESS="app.terraform.io" # Optional
Core Commands
Complete Status Check
#!/bin/bash
set -euo pipefail
TOKEN="${TFE_TOKEN:?TFE_TOKEN not set}"
BASE_URL="https://${TFE_ADDRESS:-app.terraform.io}/api/v2"
RUN_ID="${1:?Usage: $0 <run-id>}"
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/runs/$RUN_ID?include=plan,apply,cost-estimate" | \
jq -r '
"Run ID: " + .data.id,
"Status: " + .data.attributes.status,
"Message: " + (.data.attributes.message // "No message"),
"Created: " + .data.attributes."created-at",
"Has Changes: " + (.data.attributes."has-changes" | tostring),
"Auto-Apply: " + (.data.attributes."auto-apply" | tostring),
"",
"Resource Changes:",
" Additions: " + ((.included[] | select(.type == "plans") | .attributes."resource-additions") // 0 | tostring),
" Changes: " + ((.included[] | select(.type == "plans") | .attributes."resource-changes") // 0 | tostring),
" Destructions: " + ((.included[] | select(.type == "plans") | .attributes."resource-destructions") // 0 | tostring),
"",
"Actions:",
" Confirmable: " + (.data.attributes.actions."is-confirmable" | tostring),
" Cancelable: " + (.data.attributes.actions."is-cancelable" | tostring),
" Discardable: " + (.data.attributes.actions."is-discardable" | tostring),
" Force-Cancelable:" + (.data.attributes.actions."is-force-cancelable" | tostring)
'
Quick Status Only
TOKEN="${TFE_TOKEN:?TFE_TOKEN not set}"
RUN_ID="run-abc123"
curl -sf --header "Authorization: Bearer $TFE_TOKEN" \
"https://app.terraform.io/api/v2/runs/$RUN_ID" | \
jq -r '.data.attributes.status'
Status with Timestamps
curl -sf --header "Authorization: Bearer $TFE_TOKEN" \
"https://app.terraform.io/api/v2/runs/$RUN_ID" | \
jq -r '
.data.attributes |
"Status: " + .status,
"Timestamps:",
" Created: " + (."created-at" // "N/A"),
" Planned: " + (."status-timestamps"."planned-at" // "N/A"),
" Applied: " + (."status-timestamps"."applied-at" // "N/A")
'
Check Available Actions
curl -sf --header "Authorization: Bearer $TFE_TOKEN" \
"https://app.terraform.io/api/v2/runs/$RUN_ID" | \
jq '.data.attributes.actions'
Check Permissions
curl -sf --header "Authorization: Bearer $TFE_TOKEN" \
"https://app.terraform.io/api/v2/runs/$RUN_ID" | \
jq '.data.attributes.permissions'
Poll Until Complete
#!/bin/bash
set -euo pipefail
TOKEN="${TFE_TOKEN:?TFE_TOKEN not set}"
RUN_ID="${1:?Usage: $0 <run-id>}"
FINAL_STATES="applied planned_and_finished planned_and_saved discarded errored canceled force_canceled policy_soft_failed"
while true; do
STATUS=$(curl -sf --header "Authorization: Bearer $TOKEN" \
"https://app.terraform.io/api/v2/runs/$RUN_ID" | \
jq -r '.data.attributes.status')
echo "$(date +%H:%M:%S) Status: $STATUS"
if echo "$FINAL_STATES" | grep -qw "$STATUS"; then
echo "Run completed with status: $STATUS"
exit 0
fi
sleep 5
done
JSON Output
Full Run Details
curl -sf --header "Authorization: Bearer $TFE_TOKEN" \
"https://app.terraform.io/api/v2/runs/$RUN_ID" | \
jq '{
id: .data.id,
status: .data.attributes.status,
message: .data.attributes.message,
created_at: .data.attributes."created-at",
has_changes: .data.attributes."has-changes",
auto_apply: .data.attributes."auto-apply",
is_destroy: .data.attributes."is-destroy",
actions: .data.attributes.actions,
timestamps: .data.attributes."status-timestamps"
}'
With Cost Estimate
curl -sf --header "Authorization: Bearer $TFE_TOKEN" \
"https://app.terraform.io/api/v2/runs/$RUN_ID?include=cost-estimate" | \
jq '
if .included then
(.included[] | select(.type == "cost-estimates")) as $ce |
{
status: .data.attributes.status,
cost: {
prior_monthly: $ce.attributes."prior-monthly-cost",
proposed_monthly: $ce.attributes."proposed-monthly-cost",
delta_monthly: $ce.attributes."delta-monthly-cost"
}
}
else
{status: .data.attributes.status, cost: "N/A"}
end
'
Run Status Reference
Final States (run completed)
applied- Successfully appliedplanned_and_finished- Plan-only or no changesplanned_and_saved- Saved plan ready for confirmationdiscarded- User discarded the runerrored- Run encountered an errorcanceled- User canceled the runforce_canceled- Forcefully terminatedpolicy_soft_failed- Sentinel soft fail (plan-only)
Non-Final States (in progress)
pending- Initial statefetching/fetching_completed- Retrieving configqueuing/plan_queued- Waiting for capacityplanning- Plan in progressplanned- Plan complete, awaiting confirmationcost_estimating/cost_estimated- Cost estimationpolicy_checking/policy_checked- Sentinel evaluationpolicy_override- Soft fail, override availableconfirmed- User confirmed the planapply_queued/applying- Apply in progress
Action States
| Action | When Available |
|---|---|
is-confirmable | Status is planned, cost_estimated, policy_checked, or policy_override |
is-cancelable | Status is planning or applying |
is-discardable | Status is pending, planned, cost_estimated, policy_checked, or policy_override |
is-force-cancelable | Cancel was called and cooloff period elapsed |
See Also
tfc-run-logs: Get plan/apply logs for a runtfc-list-runs: List recent runs in a workspacetfc-plan-json: Get structured plan JSON output
Comments
Markdown supported