terraci

module
v0.7.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 26, 2026 License: MIT

README

TerraCi

TerraCi

Terraform Pipeline Generator for GitLab CI & GitHub Actions
Analyze dependencies, estimate costs, enforce policies, and generate optimal pipelines for Terraform/OpenTofu monorepos

Release Build License Go Report

DocumentationInstallationQuick StartExamples


Why TerraCi?

Managing Terraform in a monorepo is painful:

  • Dependencies between modules must be respected — EKS can't deploy before VPC
  • Manual pipelines are tedious to write and a nightmare to maintain
  • Full deployments waste CI minutes when only one module changed
  • No visibility into what a plan will cost or whether it violates policies

TerraCi solves all of this. Point it at your repo, and it generates correct, dependency-aware CI pipelines — with cost estimates and policy checks baked in.

Features

Pipeline Generation

  • GitLab CI & GitHub Actions support
  • Dependency-aware topological ordering
  • Parallel execution of independent modules
  • Plan + apply stages with manual approval gates
  • Changed-only mode via git diff

Intelligence

  • AWS cost estimation on every plan
  • OPA policy enforcement (local, git, OCI sources)
  • MR/PR comments with plan summaries, costs & policy results
  • Dependency graph visualization (DOT/PlantUML)

Flexibility

  • Terraform & OpenTofu support
  • Configurable directory patterns (any segment names)
  • Per-job overrides (image, secrets, tags, rules)
  • OIDC tokens & Vault secrets integration
  • Auto-detect CI provider from environment

Developer Experience

  • Interactive TUI wizard for initialization
  • Single binary, zero dependencies
  • JSON schema for IDE autocomplete
  • Shell completions (bash, zsh, fish)
  • Dry-run mode to preview changes

Installation

# Homebrew
brew install edelwud/tap/terraci

# Go
go install github.com/edelwud/terraci/cmd/terraci@latest

# Docker
docker run --rm -v $(pwd):/workspace ghcr.io/edelwud/terraci:latest generate

# Binary — download from GitHub Releases
# https://github.com/edelwud/terraci/releases

Quick Start

# Interactive setup wizard
terraci init

# Non-interactive with GitHub Actions
terraci init --ci --provider github

# Validate structure & dependencies
terraci validate

# Generate pipeline
terraci generate -o .gitlab-ci.yml                      # GitLab
terraci generate -o .github/workflows/terraform.yml     # GitHub Actions

# Only changed modules (CI)
terraci generate --changed-only --base-ref main -o .gitlab-ci.yml

How It Works

 Your Repo                    TerraCi                          CI Pipeline
┌─────────────┐    ┌──────────────────────────┐    ┌──────────────────────────┐
│ platform/   │    │ 1. Discover modules      │    │                          │
│  prod/      │───>│ 2. Parse remote_state    │───>│  plan-vpc → apply-vpc    │
│   eu-west/  │    │ 3. Build dependency DAG  │    │       ↓           ↓      │
│    vpc/     │    │ 4. Topological sort      │    │  plan-eks   plan-rds     │
│    eks/     │    │ 5. Detect CI provider    │    │       ↓           ↓      │
│    rds/     │    │ 6. Generate YAML         │    │  apply-eks  apply-rds    │
└─────────────┘    └──────────────────────────┘    │                          │
                                                   │  Output: .gitlab-ci.yml  │
                                                   │     or   workflow.yml    │
                                                   └──────────────────────────┘

1. Module Discovery

Scans directories matching a configurable pattern (default: {service}/{environment}/{region}/{module}):

platform/prod/eu-central-1/vpc/           → Module: platform/prod/eu-central-1/vpc
platform/prod/eu-central-1/eks/           → Module: platform/prod/eu-central-1/eks
platform/prod/eu-central-1/ec2/rabbitmq/  → Submodule (depth 5)

The pattern is fully configurable — {team}/{project}/{component} works too.

2. Dependency Resolution

Dependencies are extracted from terraform_remote_state data sources. The key in the remote state config must mirror your directory structure (matching structure.pattern) — this is how TerraCi maps state file paths back to modules:

# eks/main.tf — key follows the same {service}/{env}/{region}/{module} pattern
data "terraform_remote_state" "vpc" {
  backend = "s3"
  config = {
    bucket = "my-state"
    key    = "platform/prod/eu-central-1/vpc/terraform.tfstate"
    #        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    #        matches directory structure → TerraCi resolves: eks depends on vpc
    region = "eu-central-1"
  }
}

TerraCi evaluates Terraform functions statically (split, element, length, abspath, lookup, join, format, etc.) and resolves locals that depend on path.module. A common pattern that works out of the box:

locals {
  path_arr    = split("/", abspath(path.module))
  service     = local.path_arr[length(local.path_arr) - 4]
  environment = local.path_arr[length(local.path_arr) - 3]
  region      = local.path_arr[length(local.path_arr) - 2]
}

data "terraform_remote_state" "vpc" {
  backend = "s3"
  config = {
    key = "${local.service}/${local.environment}/${local.region}/vpc/terraform.tfstate"
  }
}

Limitations:

  • Static analysis only — TerraCi does not connect to remote backends or execute terraform init. Dependencies that rely on runtime values (e.g., data.terraform_remote_state.X.outputs.Y used as a key in another remote state) cannot be resolved. Derive your state keys from the filesystem path (abspath(path.module)) or explicit locals, not from other modules' outputs.
  • Backend-aware matching — When the key path alone is ambiguous (e.g., two modules with the same key in different buckets), TerraCi parses each module's terraform { backend "s3" { ... } } block and uses the bucket to disambiguate. This requires backend configuration to be defined in the module's .tf files (not solely via -backend-config CLI flags).

3. Pipeline Generation

Modules are topologically sorted and grouped into parallel execution levels:

Level 0: vpc                    (no dependencies)
Level 1: eks, rds               (depend on vpc — run in parallel)
Level 2: app                    (depends on eks)

Each level gets plan + apply stages. Apply requires the previous level to complete.

Configuration

# .terraci.yaml
provider: gitlab                         # or "github" (auto-detected from CI env)

structure:
  pattern: "{service}/{environment}/{region}/{module}"

exclude:
  - "*/test/*"
  - "*/sandbox/*"

# GitLab CI config (omitted when provider=github)
gitlab:
  image: "hashicorp/terraform:1.6"
  terraform_binary: "terraform"          # or "tofu"
  auto_approve: false
  job_defaults:
    tags: [terraform, docker]
  mr:
    comment:
      enabled: true
    summary_job:
      image: { name: "ghcr.io/edelwud/terraci:latest" }

# GitHub Actions config (omitted when provider=gitlab)
github:
  terraform_binary: "terraform"
  runs_on: "ubuntu-latest"
  permissions: { contents: read, pull-requests: write }
  pr:
    comment: { enabled: true }

# AWS cost estimation
cost:
  enabled: true
  show_in_comment: true

# OPA policy checks
policy:
  enabled: true
  sources:
    - path: policies
    - git: https://github.com/org/policies.git
      ref: main
  namespaces: [terraform]
  on_failure: block                      # block, warn, ignore

Tip: Add # yaml-language-server: $schema=https://raw.githubusercontent.com/edelwud/terraci/main/terraci.schema.json at the top of your .terraci.yaml for IDE autocomplete. Or run terraci schema to generate the schema locally.

Commands

Command Description
terraci init Interactive TUI wizard to create .terraci.yaml
terraci validate Validate project structure and dependencies
terraci generate Generate CI pipeline (GitLab CI or GitHub Actions)
terraci graph Visualize dependency graph (DOT, PlantUML, levels)
terraci cost Estimate AWS costs from Terraform plan files
terraci summary Post plan/cost/policy summary to MR/PR (CI)
terraci policy pull Download policies from configured sources
terraci policy check Evaluate plans against OPA policies
terraci schema Generate JSON schema for config validation
terraci version Show version and embedded OPA version
CI integration patterns

GitLab CI supports generative pipelines — TerraCi runs as a job inside a parent pipeline and generates a child pipeline that GitLab picks up automatically:

# .gitlab-ci.yml (parent pipeline)
generate:
  stage: generate
  image: ghcr.io/edelwud/terraci:latest
  script:
    - terraci generate --changed-only --base-ref $CI_MERGE_REQUEST_DIFF_BASE_SHA -o generated.yml
  artifacts:
    paths: [generated.yml]

deploy:
  stage: deploy
  trigger:
    include:
      - artifact: generated.yml
        job: generate

GitHub Actions does not support dynamic workflow generation at runtime. Use a pre-commit hook to regenerate the workflow file and commit it alongside your changes:

# .husky/pre-commit or .git/hooks/pre-commit
terraci generate --changed-only --base-ref main -o .github/workflows/terraform.yml
git add .github/workflows/terraform.yml
Common usage examples
# Changed modules only (for MR/PR pipelines)
terraci generate --changed-only --base-ref main -o .gitlab-ci.yml

# Filter by any segment name
terraci generate --filter environment=prod --filter service=platform

# Plan-only mode (no apply jobs)
terraci generate --plan-only

# Exclude patterns
terraci generate --exclude "*/sandbox/*" --exclude "*/test/*"

# Dependency graph as DOT
terraci graph --format dot -o deps.dot

# Show execution levels
terraci graph --format levels

# Show what depends on a module
terraci graph --module platform/prod/eu-central-1/vpc --dependents

# Policy check a specific module
terraci policy check --module platform/prod/eu-central-1/vpc --output json

# Dry run
terraci generate --dry-run

# Estimate AWS costs from plan.json files
terraci cost

# Cost for a single module
terraci cost --module platform/prod/eu-central-1/rds

# Cost as JSON
terraci cost --output json

Documentation

Full documentation is available at edelwud.github.io/terraci.

Topic Link
Getting Started guide/getting-started
Project Structure guide/project-structure
Dependencies guide/dependencies
Pipeline Generation guide/pipeline-generation
Configuration Reference config/
GitLab MR Integration config/gitlab-mr
Cost Estimation config/cost
Policy Checks config/policy
CLI Reference cli/

Contributing

Contributions are welcome! Please open an issue or pull request.

License

MIT

Directories

Path Synopsis
cmd
terraci command
xterraci command
xterraci builds custom TerraCi binaries with selected plugins, similar to xcaddy for Caddy.
xterraci builds custom TerraCi binaries with selected plugins, similar to xcaddy for Caddy.
xterraci/cmd
Package cmd provides the xterraci CLI commands.
Package cmd provides the xterraci CLI commands.
examples
internal
terraform/eval
Package eval provides HCL evaluation context and Terraform function implementations.
Package eval provides HCL evaluation context and Terraform function implementations.
terraform/plan
Package plan provides terraform plan JSON parsing functionality.
Package plan provides terraform plan JSON parsing functionality.
pkg
ci
Package ci provides shared CI/CD types and interfaces for provider-agnostic plan result handling and PR/MR comment rendering.
Package ci provides shared CI/CD types and interfaces for provider-agnostic plan result handling and PR/MR comment rendering.
config
Package config provides configuration management for terraci
Package config provides configuration management for terraci
discovery
Package discovery provides functionality for discovering Terraform modules in a directory structure following a configurable pattern like: {service}/{environment}/{region}/{module}
Package discovery provides functionality for discovering Terraform modules in a directory structure following a configurable pattern like: {service}/{environment}/{region}/{module}
errors
Package errors provides structured error types for TerraCi.
Package errors provides structured error types for TerraCi.
filter
Package filter provides filtering functionality for modules based on glob patterns and segment values.
Package filter provides filtering functionality for modules based on glob patterns and segment values.
graph
Package graph provides dependency graph construction and analysis.
Package graph provides dependency graph construction and analysis.
log
Package log provides structured logging for TerraCi CLI
Package log provides structured logging for TerraCi CLI
parser
Package parser provides HCL parsing functionality for Terraform files.
Package parser provides HCL parsing functionality for Terraform files.
plugin
Package plugin provides the compile-time plugin system for TerraCi.
Package plugin provides the compile-time plugin system for TerraCi.
workflow
Package workflow provides shared orchestration logic for module discovery, filtering, dependency extraction, and graph building.
Package workflow provides shared orchestration logic for module discovery, filtering, dependency extraction, and graph building.
plugins
cost
Package cost provides the AWS cost estimation plugin for TerraCi.
Package cost provides the AWS cost estimation plugin for TerraCi.
cost/internal
Package cost provides AWS cost estimation for Terraform plans
Package cost provides AWS cost estimation for Terraform plans
cost/internal/aws
Package aws provides AWS resource cost estimation handlers
Package aws provides AWS resource cost estimation handlers
cost/internal/pricing
Package pricing provides AWS Price List API integration
Package pricing provides AWS Price List API integration
git
Package git provides the Git change detection plugin for TerraCi.
Package git provides the Git change detection plugin for TerraCi.
git/internal
Package git provides Git integration for detecting changed files.
Package git provides Git integration for detecting changed files.
github
Package github provides the GitHub Actions plugin for TerraCi.
Package github provides the GitHub Actions plugin for TerraCi.
github/internal
Package githubci provides GitHub API client for PR integration
Package githubci provides GitHub API client for PR integration
gitlab
Package gitlab provides the GitLab CI plugin for TerraCi.
Package gitlab provides the GitLab CI plugin for TerraCi.
gitlab/internal
Package gitlabci provides GitLab API client for MR integration
Package gitlabci provides GitLab API client for MR integration
policy
Package policy provides the OPA policy check plugin for TerraCi.
Package policy provides the OPA policy check plugin for TerraCi.
policy/internal
Package policy provides OPA-based policy checking for Terraform plans
Package policy provides OPA-based policy checking for Terraform plans
summary
Package summary provides the summary plugin for TerraCi.
Package summary provides the summary plugin for TerraCi.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL