Spacelift
Spacelift orchestrates Terraform via GitOps: GitHub pushes trigger runs,
policies govern behavior, contexts inject config, workers execute runs.
- API:
https://<account>.app.spacelift.io/graphql
- Terraform provider:
spacelift-io/spacelift
- spacectl:
brew install spacelift-io/spacelift/spacectl
Core Concepts
| Concept |
Description |
| Stack |
Terraform project unit: repo + branch + settings + state |
| Run |
Execution of terraform plan (proposed) or plan+apply (tracked) |
| Policy |
OPA Rego rule set governing stack behavior (9 types) |
| Context |
Reusable bundle of env vars + mounted files + hooks |
| Worker Pool |
Set of runners executing runs (public Spacelift-hosted or private) |
| Space |
Organizational boundary for access control and resource scoping |
GitOps Workflow
feature branch push
→ push policy → propose
→ proposed run: terraform plan
→ commit status reported to PR
PR merged to tracked branch (e.g., main)
→ push policy → track
→ tracked run: terraform plan
→ if autodeploy: auto-apply
→ else: unconfirmed state → human confirms → apply
Run States
| State |
Meaning |
| QUEUED |
Waiting for worker; approval policies evaluated here |
| INITIALIZING |
Worker starting, downloading source |
| PLANNING |
terraform plan running |
| UNCONFIRMED |
Plan done, awaiting human confirm (or autodeploy blocked) |
| CONFIRMED |
Human confirmed, apply will start |
| APPLYING |
terraform apply running |
| FINISHED |
Completed successfully |
| FAILED |
Run failed at some phase |
| DISCARDED |
Manually abandoned |
spacectl Quick Reference
Auth (CI/Agent — non-interactive)
export SPACELIFT_API_KEY_ENDPOINT=https://myorg.app.spacelift.io
export SPACELIFT_API_KEY_ID=$SECRET_KEY_ID
export SPACELIFT_API_KEY_SECRET=$SECRET_KEY_SECRET
GitHub Actions
- uses: spacelift-io/setup-spacectl@main
- run: spacectl stack deploy --id my-stack --auto-confirm --tail
env:
SPACELIFT_API_KEY_ENDPOINT: https://myorg.app.spacelift.io
SPACELIFT_API_KEY_ID: ${{ secrets.SPACELIFT_API_KEY_ID }}
SPACELIFT_API_KEY_SECRET: ${{ secrets.SPACELIFT_API_KEY_SECRET }}
Key Commands
spacectl stack list
spacectl stack deploy --id <stack> --auto-confirm --tail
spacectl stack task --id <stack> --tail 'terraform output -json'
spacectl run list --stack <stack>
spacectl run logs --stack <stack> --run <run-id>
spacectl run confirm --stack <stack> --run <run-id>
spacectl workerpool list
spacectl profile export-token # get bearer token for API calls
Stack Settings Quick Reference
| Field |
Key Values |
| Branch |
Tracked branch — pushes here trigger tracked runs |
| Project root |
Subdirectory for Terraform root (monorepo) |
| Project globs |
Sparse checkout paths (requires git checkout mode) |
| Autodeploy |
true = auto-apply on clean plan |
| Autoretry |
true = retry proposed runs when state changes (private worker only) |
| Worker pool |
Assign private pool; required for drift detection |
| Runner image |
Custom Docker image (default: public.ecr.aws/spacelift/runner-terraform:latest) |
| Labels |
Used by policies for auto-attach and filtering |
| Deletion protection |
Prevent accidental stack deletion |
Policy Types Quick Reference
| Type |
Fires when |
Key outputs |
| Push |
Git push or PR event |
track, propose, ignore, cancel |
| Plan |
After terraform plan |
deny (fail), warn (require review) |
| Trigger |
Tracked run reaches terminal state |
trigger (stack IDs to cascade) |
| Approval |
Run enters queued/unconfirmed |
approve, reject |
| Login |
User login attempt |
allow, deny, admin |
| Stack Access |
Stack access check |
read, write, admin, deny |
| Notification |
Any run state change |
notification targets |
| Task |
Before task runs |
allow, deny |
| Run Init |
Before run starts (deprecated) |
allow, deny |
All policies use Rego v1 (package spacelift). Auto-attach via label autoattach:<label>.
Most Common Patterns
# Push: standard GitOps
track if input.push.branch == input.stack.branch
propose if not is_null(input.pull_request)
ignore if { not track; not propose }
# Plan: block deletions
deny contains sprintf("Deletion not allowed: %s", [c.entity.address]) if {
some c in input.spacelift.run.changes; c.action == "deleted"
}
# Plan: manual review for drift
warn contains "Drift reconciliation requires manual approval" if {
input.spacelift.run.drift_detection
}
# Approval: require 1 reviewer
approve if count(input.reviews.current.approvals) >= 1
Reference Files
| File |
Read when |
references/github-terraform-workflow.md |
Setting up GitHub App, branch tracking, PR status checks, push policy patterns, monorepo sparse checkout |
references/stack-configuration.md |
Stack creation fields, VCS settings, Terraform settings, hooks, scheduling, stack dependencies |
references/policies.md |
All 9 policy types with full input schemas, Rego v1 examples, workbench testing |
references/spacectl.md |
CLI installation, auth methods, stack/run/worker commands, CI agent patterns, GraphQL API |
references/contexts-and-config.md |
Context creation, auto-attach labels, priority/conflict resolution, .spacelift/config.yml, env var precedence |
references/worker-pools.md |
Private worker setup (CSR → pool → launch), config vars, network requirements, sizing |
references/drift-detection.md |
Scheduling, reconciliation, plan/trigger policy integration, drift run limits |
references/gcp-integration.md |
Setting up GCP OIDC (WIF), native GCP integration, credential config JSON, Terraform provider auth, hierarchical space access, direct resource access |
references/terraform-provider.md |
Terraform provider config, resource+data source inventory, HCL schemas for all core resources, AWS integration setup, import IDs |
1---2name: spacelift-terraform3description: Spacelift for Terraform GitOps. Use when working with Spacelift stacks, runs, policies, contexts, worker pools, drift detection, or spacectl CLI.4---56# Spacelift78Spacelift orchestrates Terraform via GitOps: GitHub pushes trigger runs,9policies govern behavior, contexts inject config, workers execute runs.1011- **API**: `https://<account>.app.spacelift.io/graphql`12- **Terraform provider**: `spacelift-io/spacelift`13- **spacectl**: `brew install spacelift-io/spacelift/spacectl`1415## Core Concepts1617| Concept | Description |18| --------------- | ------------------------------------------------------------------ |19| **Stack** | Terraform project unit: repo + branch + settings + state |20| **Run** | Execution of `terraform plan` (proposed) or `plan+apply` (tracked) |21| **Policy** | OPA Rego rule set governing stack behavior (9 types) |22| **Context** | Reusable bundle of env vars + mounted files + hooks |23| **Worker Pool** | Set of runners executing runs (public Spacelift-hosted or private) |24| **Space** | Organizational boundary for access control and resource scoping |2526---2728## GitOps Workflow2930```31feature branch push32 → push policy → propose33 → proposed run: terraform plan34 → commit status reported to PR3536PR merged to tracked branch (e.g., main)37 → push policy → track38 → tracked run: terraform plan39 → if autodeploy: auto-apply40 → else: unconfirmed state → human confirms → apply41```4243### Run States4445| State | Meaning |46| ------------ | --------------------------------------------------------- |47| QUEUED | Waiting for worker; approval policies evaluated here |48| INITIALIZING | Worker starting, downloading source |49| PLANNING | `terraform plan` running |50| UNCONFIRMED | Plan done, awaiting human confirm (or autodeploy blocked) |51| CONFIRMED | Human confirmed, apply will start |52| APPLYING | `terraform apply` running |53| FINISHED | Completed successfully |54| FAILED | Run failed at some phase |55| DISCARDED | Manually abandoned |5657---5859## spacectl Quick Reference6061### Auth (CI/Agent — non-interactive)6263```bash64export SPACELIFT_API_KEY_ENDPOINT=https://myorg.app.spacelift.io65export SPACELIFT_API_KEY_ID=$SECRET_KEY_ID66export SPACELIFT_API_KEY_SECRET=$SECRET_KEY_SECRET67```6869### GitHub Actions7071```yaml72- uses: spacelift-io/setup-spacectl@main73- run: spacectl stack deploy --id my-stack --auto-confirm --tail74 env:75 SPACELIFT_API_KEY_ENDPOINT: https://myorg.app.spacelift.io76 SPACELIFT_API_KEY_ID: ${{ secrets.SPACELIFT_API_KEY_ID }}77 SPACELIFT_API_KEY_SECRET: ${{ secrets.SPACELIFT_API_KEY_SECRET }}78```7980### Key Commands8182```bash83spacectl stack list84spacectl stack deploy --id <stack> --auto-confirm --tail85spacectl stack task --id <stack> --tail 'terraform output -json'86spacectl run list --stack <stack>87spacectl run logs --stack <stack> --run <run-id>88spacectl run confirm --stack <stack> --run <run-id>89spacectl workerpool list90spacectl profile export-token # get bearer token for API calls91```9293---9495## Stack Settings Quick Reference9697| Field | Key Values |98| ------------------- | --------------------------------------------------------------------------------- |99| Branch | Tracked branch — pushes here trigger tracked runs |100| Project root | Subdirectory for Terraform root (monorepo) |101| Project globs | Sparse checkout paths (requires git checkout mode) |102| Autodeploy | `true` = auto-apply on clean plan |103| Autoretry | `true` = retry proposed runs when state changes (private worker only) |104| Worker pool | Assign private pool; required for drift detection |105| Runner image | Custom Docker image (default: `public.ecr.aws/spacelift/runner-terraform:latest`) |106| Labels | Used by policies for auto-attach and filtering |107| Deletion protection | Prevent accidental stack deletion |108109---110111## Policy Types Quick Reference112113| Type | Fires when | Key outputs |114| ---------------- | ---------------------------------- | -------------------------------------- |115| **Push** | Git push or PR event | `track`, `propose`, `ignore`, `cancel` |116| **Plan** | After `terraform plan` | `deny` (fail), `warn` (require review) |117| **Trigger** | Tracked run reaches terminal state | `trigger` (stack IDs to cascade) |118| **Approval** | Run enters queued/unconfirmed | `approve`, `reject` |119| **Login** | User login attempt | `allow`, `deny`, `admin` |120| **Stack Access** | Stack access check | `read`, `write`, `admin`, `deny` |121| **Notification** | Any run state change | notification targets |122| **Task** | Before task runs | `allow`, `deny` |123| **Run Init** | Before run starts (deprecated) | `allow`, `deny` |124125All policies use **Rego v1** (`package spacelift`). Auto-attach via label `autoattach:<label>`.126127### Most Common Patterns128129```opa130# Push: standard GitOps131track if input.push.branch == input.stack.branch132propose if not is_null(input.pull_request)133ignore if { not track; not propose }134135# Plan: block deletions136deny contains sprintf("Deletion not allowed: %s", [c.entity.address]) if {137 some c in input.spacelift.run.changes; c.action == "deleted"138}139140# Plan: manual review for drift141warn contains "Drift reconciliation requires manual approval" if {142 input.spacelift.run.drift_detection143}144145# Approval: require 1 reviewer146approve if count(input.reviews.current.approvals) >= 1147```148149---150151## Reference Files152153| File | Read when |154| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |155| `references/github-terraform-workflow.md` | Setting up GitHub App, branch tracking, PR status checks, push policy patterns, monorepo sparse checkout |156| `references/stack-configuration.md` | Stack creation fields, VCS settings, Terraform settings, hooks, scheduling, stack dependencies |157| `references/policies.md` | All 9 policy types with full input schemas, Rego v1 examples, workbench testing |158| `references/spacectl.md` | CLI installation, auth methods, stack/run/worker commands, CI agent patterns, GraphQL API |159| `references/contexts-and-config.md` | Context creation, auto-attach labels, priority/conflict resolution, `.spacelift/config.yml`, env var precedence |160| `references/worker-pools.md` | Private worker setup (CSR → pool → launch), config vars, network requirements, sizing |161| `references/drift-detection.md` | Scheduling, reconciliation, plan/trigger policy integration, drift run limits |162| `references/gcp-integration.md` | Setting up GCP OIDC (WIF), native GCP integration, credential config JSON, Terraform provider auth, hierarchical space access, direct resource access |163| `references/terraform-provider.md` | Terraform provider config, resource+data source inventory, HCL schemas for all core resources, AWS integration setup, import IDs |