Temporal Terraform Orchestrator
FreeNot checkedOrchestrates multi-workspace Terraform deployments with Temporal workflows
About
Orchestrates multi-workspace Terraform deployments with Temporal workflows
README
A Temporal-based workflow orchestration system for managing multi-workspace Terraform deployments with dependency resolution, variable passing between workspaces, and MCP server integration for AI-driven automation.
Table of Contents
- Overview
- Architecture
- Prerequisites
- Quick Start
- CLI Starter
- MCP Server
- Configuration Reference (infra.yaml)
- Testing
- Repository Layout
- Troubleshooting
Overview
This project provides a robust infrastructure-as-code orchestration layer using Temporal workflows to manage Terraform operations across multiple workspaces with:
- Dependency management: Define workspace dependencies and the system executes them in the correct order
- Output propagation: Pass Terraform outputs from one workspace as inputs to dependent workspaces
- Parallel execution: Independent workspaces run concurrently for faster deployments
- Durability: Temporal provides automatic retries, state persistence, and failure recovery
- AI integration: MCP server enables AI agents to trigger and monitor infrastructure deployments
ParentWorkflow (Orchestrator)
│
├─> TerraformWorkflow (vpc) ← runs first (no dependencies)
│
├─> TerraformWorkflow (vpc-2) ← runs in parallel with vpc
│
├─> TerraformWorkflow (subnets) ← waits for vpc, receives vpc_id output
│
└─> TerraformWorkflow (eks) ← waits for vpc + subnets, receives both outputs
Architecture
Workflow Components
ParentWorkflow: The orchestrator that:
- Validates and normalizes the configuration
- Builds a dependency DAG (Directed Acyclic Graph)
- Starts root workspaces (those with no dependencies) immediately
- Listens for completion signals and starts dependent workspaces when ready
- Propagates outputs between workspaces based on input mappings
TerraformWorkflow: Executes Terraform operations for a single workspace:
terraform init- Initialize the workspaceterraform plan- Create execution plan (with-detailed-exitcodeto detect changes)terraform show -json- Validate the plan outputterraform apply- Apply changes (skipped if no changes detected)terraform output -json- Capture outputs for downstream workspaces- Signals completion back to ParentWorkflow
- Enters "hosting mode" to spawn child workflows for nested dependencies
Hosting Architecture
Child workflows are spawned as nested children of their "host" workflow (the deepest dependency). This creates a natural hierarchy where:
- Root workspaces are direct children of ParentWorkflow
- Dependent workspaces become children of their host workflow
- All workflows signal completion back to the ParentWorkflow orchestrator
Prerequisites
- Go 1.23+
- Terraform CLI >= 1.5 - Available on PATH
- Temporal Server - Running at default address
localhost:7233(or setTEMPORAL_ADDRESS) - AWS Credentials - If using real AWS resources (the examples use mock outputs)
Quick Start
Install dependencies:
go mod tidyStart Temporal (if not already running):
temporal server start-devStart the worker:
go run ./cmd/workerExecute the workflow:
go run ./cmd/starter -config infra.yamlMonitor execution in the Temporal Web UI at
http://localhost:8233
CLI Starter
The CLI starter (cmd/starter) initiates workflow execution from a YAML configuration file.
Usage
go run ./cmd/starter [flags]
Flags
| Flag | Default | Description |
|---|---|---|
-config |
infra.yaml |
Path to the infrastructure configuration file |
-task-queue |
terraform-task-queue |
Temporal task queue name |
-workflow-id |
terraform-parent-workflow |
Custom workflow ID for tracking |
Examples
# Run with default settings
go run ./cmd/starter
# Specify a custom config file
go run ./cmd/starter -config ./environments/production.yaml
# Use a custom workflow ID for tracking
go run ./cmd/starter -config infra.yaml -workflow-id "deploy-prod-2024-01-15"
Behavior
- Reads and parses the YAML configuration file
- Validates the configuration (checks for cycles, missing dependencies, etc.)
- Normalizes paths relative to
workspace_root - Starts the ParentWorkflow via Temporal
- Waits for workflow completion and reports success/failure
MCP Server
The MCP (Model Context Protocol) server enables AI agents and automation tools to interact with the orchestration system.
Starting the Server
go run ./cmd/mcp-server
The server runs on stdio and communicates via JSON-RPC, following the MCP specification.
Available Tools
list_workflows
Lists available workflows and configured workspaces from the configuration file.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
config_path |
string | No | infra.yaml |
Path to YAML config file |
Response example:
{
"config_path": "infra.yaml",
"workspace_root": ".",
"workflows": [
{
"name": "ParentWorkflow",
"description": "Orchestrates terraform operations across multiple workspaces with dependencies",
"configured_workspaces": [
{
"name": "vpc",
"kind": "terraform",
"dir": "/abs/path/vpc",
"dependsOn": []
},
{
"name": "subnets",
"kind": "terraform",
"dir": "/abs/path/subnets",
"dependsOn": ["vpc"]
}
],
"workspace_count": 2
}
]
}
execute_workflow
Starts a Terraform orchestration workflow.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
workflow_name |
string | Yes | Must be ParentWorkflow |
config_path |
string | No* | Path to YAML config file |
config |
object | No* | Inline configuration payload (JSON) |
*Either config_path or config must be provided.
Response example:
Workflow started successfully.
WorkflowID: terraform-parent-workflow-12345
RunID: abc123-def456-ghi789
get_workflow_status
Gets the status of a running or completed workflow.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
workflow_id |
string | Yes | The workflow ID to check |
Response example:
Workflow: terraform-parent-workflow-12345
Status: WORKFLOW_EXECUTION_STATUS_COMPLETED
Started At: 2024-01-15 10:30:00
Finished At: 2024-01-15 10:35:42
Integration with AI Agents
The MCP server is designed for integration with AI coding assistants (like Cursor, Claude, etc.). Add it to your MCP configuration:
{
"mcpServers": {
"temporal-terraform": {
"command": "/path/to/mcp-server",
"args": []
}
}
}
Configuration Reference (infra.yaml)
The configuration file defines your infrastructure workspaces and their relationships.
Complete Schema
# Base path for resolving relative directories (optional)
workspace_root: '.'
# List of workspaces to orchestrate
workspaces:
- name: string # Required: Unique workspace identifier
kind: string # Optional: "terraform" (default and only supported value)
dir: string # Required: Path to Terraform directory
tfvars: string # Optional: Path to .tfvars file
dependsOn: [string] # Optional: List of workspace names this depends on
inputs: [InputMapping] # Optional: Variable mappings from dependencies
operations: [string] # Optional: Operations to run (default: [init, validate, plan, apply])
taskQueue: string # Optional: Override the Temporal task queue
Input Mapping Schema
inputs:
- sourceWorkspace: string # Name of the dependency workspace
sourceOutput: string # Name of the Terraform output to read
targetVar: string # Name of the Terraform variable to set
Complete Example
workspace_root: .
workspaces:
# VPC workspace - no dependencies, runs first
- name: vpc
kind: terraform
dir: terraform/examples/vpc
tfvars: terraform/examples/vpc/vpc.tfvars
dependsOn: []
taskQueue: terraform-task-queue
# Second VPC - independent, runs in parallel with first
- name: vpc-2
kind: terraform
dir: terraform/examples/vpc-2
tfvars: terraform/examples/vpc-2/vpc.tfvars
dependsOn: []
taskQueue: terraform-task-queue
# Subnets - depends on VPC, receives vpc_id output
- name: subnets
kind: terraform
dir: terraform/examples/subnets
tfvars: terraform/examples/subnets/subnets.tfvars
dependsOn:
- vpc
inputs:
- sourceWorkspace: vpc
sourceOutput: vpc_id
targetVar: vpc_id
taskQueue: terraform-task-queue
# EKS - depends on both VPC and subnets, receives outputs from both
- name: eks
kind: terraform
dir: terraform/examples/eks
tfvars: terraform/examples/eks/eks.tfvars
dependsOn:
- vpc
- subnets
inputs:
- sourceWorkspace: vpc
sourceOutput: vpc_id
targetVar: vpc_id
- sourceWorkspace: subnets
sourceOutput: subnet_ids
targetVar: subnet_ids
Key Concepts
Workspace Dependencies (dependsOn)
- Define execution order constraints
- Multiple dependencies create AND conditions (all must complete)
- Independent workspaces (empty or no
dependsOn) run in parallel - Cycles are detected and rejected during validation
Output to Input Propagation (inputs)
The inputs array maps Terraform outputs from dependency workspaces to variables in the current workspace:
# In the subnets workspace config
inputs:
- sourceWorkspace: vpc # Get output from 'vpc' workspace
sourceOutput: vpc_id # Read the 'vpc_id' output
targetVar: vpc_id # Pass as -var vpc_id=<value>
This allows you to:
- Chain infrastructure components together
- Pass resource IDs between workspaces
- Build complex dependency graphs
Transitive Dependencies
Input mappings support transitive dependencies. For example, if C depends on B, and B depends on A, then C can map outputs from both B AND A:
workspaces:
- name: a
dir: ./a
- name: b
dir: ./b
dependsOn: [a]
- name: c
dir: ./c
dependsOn: [b]
inputs:
- sourceWorkspace: a # Valid: 'a' is a transitive dependency
sourceOutput: some_output
targetVar: from_a
- sourceWorkspace: b # Valid: 'b' is a direct dependency
sourceOutput: other_output
targetVar: from_b
Operations Control
The operations field allows fine-grained control over which Terraform operations to run for each workspace:
operations: [init, validate, plan, apply] # Full apply mode (default)
operations: [init, validate, plan] # Plan-only mode (no apply)
Valid operations:
init- Initialize the Terraform workspace (required)validate- Validate Terraform configuration (required)plan- Generate execution planapply- Apply changes to infrastructure
Requirements:
initandvalidateare always required- Operations must be specified in order:
init→validate→plan→apply applyrequiresplanto be present
Use cases:
- Plan-only mode: Set
operations: [init, validate, plan]for review/approval workflows - Full apply mode: Set
operations: [init, validate, plan, apply]for automatic deployments (default)
Path Resolution
workspace_root: Base path for resolving relative paths- Relative paths in
dirandtfvarsare joined withworkspace_root - Absolute paths are used as-is
- The current working directory is used if
workspace_rootis empty
Testing
Run all tests:
go test ./...
Test Coverage
- Config validation: Cycle detection, duplicate names, missing dependencies, input mapping validation
- Parent workflow: Execution order, dependency waiting, signal handling
- Activities: Uses a shim Terraform binary that simulates CLI behavior
The tests use a fake Terraform binary that:
- Returns exit code 2 for
plan(simulating changes) - Creates plan files on disk
- Returns mock JSON for
outputandshowcommands
Repository Layout
.
├── activities/ # Terraform CLI wrapper activities
│ ├── terraform_activities.go # Init, Plan, Validate, Apply, Output
│ └── terraform_activities_test.go
├── cmd/
│ ├── mcp-server/ # MCP server for AI integration
│ ├── starter/ # CLI to start workflows
│ └── worker/ # Temporal worker process
├── terraform/examples/ # Sample Terraform workspaces
│ ├── vpc/
│ ├── vpc-2/
│ ├── subnets/
│ └── eks/
├── utils/ # Shared constants
├── workflow/ # Temporal workflow definitions
│ ├── config.go # Configuration types and validation
│ ├── parent_workflow.go # Orchestrator workflow
│ └── terraform_workflow.go # Per-workspace workflow
├── go.mod
├── go.sum
├── infra.yaml # Example configuration
└── README.md
Troubleshooting
Worker Connection Issues
Unable to create client: ...
Solution: Ensure Temporal server is running and accessible. Check TEMPORAL_ADDRESS if using a non-default location.
Workflow Fails Immediately
Invalid config: ...
Solution: Validate your infra.yaml:
- Check for duplicate workspace names
- Ensure all
dependsOnreferences exist - Verify there are no circular dependencies
- Confirm
inputsreference valid dependencies
Terraform Errors
terraform init failed: ...
Solutions:
- Ensure
terraformis on PATH - Verify the workspace
dirpath exists - Check for valid Terraform configuration in the directory
- For AWS resources, ensure credentials are configured
Plan File Not Found
plan file not found for apply: ...
Solution: This typically indicates terraform plan failed silently. Check:
- Directory permissions
- Terraform initialization state
- Provider configurations
MCP Server Not Responding
Solution: The MCP server runs on stdio. Ensure your client is configured to communicate via stdin/stdout, not HTTP.
Installing Temporal Terraform Orchestrator
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/fakoli/ai-driven-temporal-to-iacFAQ
Is Temporal Terraform Orchestrator MCP free?
Yes, Temporal Terraform Orchestrator MCP is free — one-click install via Unyly at no cost.
Does Temporal Terraform Orchestrator need an API key?
No, Temporal Terraform Orchestrator runs without API keys or environment variables.
Is Temporal Terraform Orchestrator hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Temporal Terraform Orchestrator in Claude Desktop, Claude Code or Cursor?
Open Temporal Terraform Orchestrator on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectCompare Temporal Terraform Orchestrator with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
