How It Works
- Ctrlplane renders a workspace configuration from your template
- The workspace is created or updated via Terraform Cloud API
- Variables are synced to match your template
- A webhook notification configuration (
ctrlplane-webhook) is created on the workspace (idempotent) - A run is triggered with auto-apply
- Terraform Cloud sends webhook notifications as the run progresses
- The ctrlplane API receives webhooks and updates job status in the database
Prerequisites
- Terraform Cloud or Terraform Enterprise account
- API token with workspace, run, and notification configuration permissions
- VCS connection (optional, for Git-based workflows)
- A reachable webhook endpoint (the ctrlplane API must be accessible from TFC)
Configuration
Job Agent Setup
Create a job agent with typetfe:
Deployment Configuration
| Field | Required | Default | Description |
|---|---|---|---|
organization | Yes | Terraform Cloud organization | |
address | Yes | Terraform Cloud/Enterprise URL | |
token | Yes | API token | |
template | Yes | Go template for workspace configuration | |
webhookUrl | Yes | Ctrlplane API endpoint for TFC notifications (e.g. https://ctrlplane.example.com/api/tfe/webhook) | |
triggerRunOnChange | No | true | Whether to create a TFC run on dispatch. When false, only the workspace and variables are synced. |
Environment Variables
| Variable | Where | Description |
|---|---|---|
TFE_WEBHOOK_SECRET | API | HMAC secret for verifying incoming TFC webhooks |
TFE_WEBHOOK_SECRET | Workspace Engine | Same secret, used when creating notification configs on TFC |
TFE_WEBHOOK_SECRET.
Webhook Status Mapping
When TFC sends a notification, the webhook handler maps the trigger to a ctrlplane job status:| TFC Trigger | Example Run Status | Ctrlplane Status |
|---|---|---|
run:created | pending | pending |
run:planning | planning | inProgress |
run:needs_attention | planned (confirmable), policy_override | actionRequired |
run:applying | applying | inProgress |
run:completed | applied, planned_and_finished | successful |
run:errored | errored | failure |
Workspace Template
The template defines the Terraform Cloud workspace:| Field | Type | Description |
|---|---|---|
name | string | Workspace name (required) |
description | string | Workspace description |
execution_mode | string | remote, local, or agent |
auto_apply | bool | Auto-apply after plan |
terraform_version | string | Terraform version to use |
working_directory | string | Subdirectory for Terraform files |
vcs_repo | object | VCS repository settings |
variables | array | Workspace variables |
VCS Repository Settings
Variable Configuration
Template Context
The template has access to the full dispatch context:| Variable | Description |
|---|---|
.deployment | Deployment details |
.environment | Environment details |
.resource | Target resource (config, metadata) |
.release | Release details |
.version | Deployment version (tag, name) |
.variables | Merged deployment variables |
triggerRunOnChange: false
When triggerRunOnChange is set to false, the dispatcher will:
- Upsert the workspace
- Sync variables
- Ensure the notification config exists
- Skip creating a run
Note: Correlating VCS-triggered runs back to ctrlplane jobs (by workspace name/ID instead of run ID) is a planned follow-up.
Example: Multi-Environment Infrastructure
Example: Agent-Based Execution
For private infrastructure, use agent execution mode:Terraform Provider Configuration
When using the ctrlplane Terraform provider:Troubleshooting
Workspace creation fails
- Verify organization name is correct
- Check API token has workspace:write permission
- Ensure workspace name is valid (alphanumeric, hyphens, underscores)
VCS connection errors
- Verify OAuth token ID is correct
- Check repository exists and is accessible
- Ensure branch or tag exists
Run fails to start
- Check workspace has valid configuration
- Verify VCS connection is working
- Review workspace settings in Terraform Cloud UI
Variables not updating
- Verify variable keys match expected format
- Check for duplicate variable definitions
- Sensitive variables won’t show values in UI
Webhook returns 401
- Check
TFE_WEBHOOK_SECRETis set on the API - Verify the same secret was used when creating the notification config on TFC
- Ensure the
x-tfe-notification-signatureheader is present
No webhook notifications received
- Verify the
webhookUrlis reachable from Terraform Cloud - Check the notification config exists on the TFC workspace (Settings > Notifications)
- Review TFC’s notification delivery log for errors
- For local development, use smee.io or localtunnel to expose your API
Job stays in inProgress
- Verify webhooks are reaching the API (check API logs for
POST /api/tfe/webhook) - Check the TFC run status directly in the TFC UI