Pipeline Generation
TerraCi generates CI pipelines that respect module dependencies and enable parallel execution. Both GitLab CI and GitHub Actions are fully supported.
Basic Generation
Generate a pipeline for all modules:
# GitLab CI
terraci generate -o .gitlab-ci.yml
# GitHub Actions
terraci generate -o .github/workflows/terraform.ymlThe provider is selected via TERRACI_PROVIDER, auto-detected from the environment (GITLAB_CI env var selects GitLab, GITHUB_ACTIONS selects GitHub Actions), or inferred from a single active provider.
GitLab CI Pipeline Structure
The generated GitLab CI pipeline includes:
Stages
GitLab stages are derived from topological DAG layers:
stages:
- deploy-0
- deploy-1
- deploy-2
- deploy-3Variables
Global variables are set from configuration:
variables:
TF_IN_AUTOMATION: "true"
TF_INPUT: "false"Default Configuration
Shared job settings:
default:
image: hashicorp/terraform:1.6
before_script:
- terraform init
tags:
- terraform
- dockerJobs
plan-platform-prod-us-east-1-vpc:
stage: deploy-0
script:
- cd platform/prod/us-east-1/vpc
- terraform plan -out=plan.tfplan
variables:
TF_MODULE_PATH: platform/prod/us-east-1/vpc
TF_SERVICE: platform
TF_ENVIRONMENT: prod
TF_REGION: us-east-1
TF_MODULE: vpc
artifacts:
paths:
- platform/prod/us-east-1/vpc/plan.tfplan
expire_in: 1 day
resource_group: platform/prod/us-east-1/vpc
apply-platform-prod-us-east-1-vpc:
stage: deploy-1
script:
- cd platform/prod/us-east-1/vpc
- terraform apply plan.tfplan
needs:
- job: plan-platform-prod-us-east-1-vpc
when: manual
resource_group: platform/prod/us-east-1/vpcDynamic Environment Variables
The TF_SERVICE, TF_ENVIRONMENT, TF_REGION, TF_MODULE variables are generated dynamically from the configured pattern segments. If your pattern is {team}/{env}/{module}, the variables would be TF_TEAM, TF_ENV, and TF_MODULE instead.
Job Dependencies
Jobs use GitLab's needs keyword to express dependencies:
plan-platform-prod-us-east-1-eks:
stage: deploy-2
needs:
- job: apply-platform-prod-us-east-1-vpc # Wait for VPC
# ...
apply-platform-prod-us-east-1-eks:
stage: deploy-3
needs:
- job: plan-platform-prod-us-east-1-eks # Wait for own plan
- job: apply-platform-prod-us-east-1-vpc # Wait for VPC
# ...Parallel Execution
Independent DAG jobs in the same topological group can run in parallel:
GitHub Actions Workflow Structure
When using the GitHub Actions provider, TerraCi generates a workflow file with jobs connected by DAG dependencies:
name: Terraform
on:
pull_request:
workflow_dispatch:
jobs:
plan-platform-prod-us-east-1-vpc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Plan
run: |
cd platform/prod/us-east-1/vpc
terraform plan -out=plan.tfplan
- uses: actions/upload-artifact@v4
with:
name: plan-platform-prod-us-east-1-vpc
path: platform/prod/us-east-1/vpc/plan.tfplan
apply-platform-prod-us-east-1-vpc:
needs: [plan-platform-prod-us-east-1-vpc]
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: plan-platform-prod-us-east-1-vpc
- name: Apply
run: |
cd platform/prod/us-east-1/vpc
terraform apply plan.tfplanGitHub Actions jobs use needs for dependency ordering, actions/upload-artifact and actions/download-artifact for passing plan files between jobs, and environment for approval gates.
Changed-Only Pipelines
Generate pipelines for changed modules and their related modules:
terraci generate --changed-only --base-ref main -o .gitlab-ci.ymlThis:
- Detects files changed since
mainbranch - Maps changed files to modules
- Finds all modules that depend on changed modules (dependents)
- Finds all modules that changed modules depend on (dependencies)
- Generates a pipeline only for affected modules
Example: Root module changes
If vpc/main.tf changes:
vpcis included (changed)eksis included (depends on vpc)rdsis included (depends on vpc)appis included (depends on eks and rds)
Unchanged modules like monitoring (no vpc dependency) are excluded.
Example: Leaf module changes
If eks/main.tf changes:
eksis included (changed)vpcis included (eks depends on vpc)appis included (depends on eks)
This ensures proper pipeline execution order - dependencies are deployed before the changed module, and dependents are deployed after.
Resource Groups
Each module uses a resource_group to prevent concurrent applies:
apply-platform-prod-us-east-1-vpc:
resource_group: platform/prod/us-east-1/vpcThis ensures only one apply job runs per module at a time.
Configuration Options
Plan Jobs
Enable or disable plan jobs globally via the top-level execution: section (it applies to both providers):
execution:
extensions:
gitlab:Apply Scheduling
Use provider overwrites to control apply scheduling. For example, make GitLab apply jobs manual:
extensions:
gitlab:
overwrites:
- type: apply
when: manualStage Prefix
Customize stage names:
extensions:
gitlab:
stages_prefix: "terraform" # terraform-0, terraform-1, ...Custom Scripts
Add custom before/after scripts via job_defaults:
extensions:
gitlab:
job_defaults:
before_script:
- terraform init
- terraform workspace select ${TF_ENVIRONMENT} || terraform workspace new ${TF_ENVIRONMENT}
after_script:
- terraform output -json > outputs.jsonRunner Tags
Specify GitLab runner tags via job_defaults:
extensions:
gitlab:
job_defaults:
tags:
- terraform
- docker
- awsDry Run
Preview what would be generated:
terraci generate --dry-runOutput:
Dry Run Summary:
Total modules: 12
Affected modules: 5
Stages: 6
Jobs: 10
Job Groups:
dag-level-0: [plan-vpc]
dag-level-1: [apply-vpc]
dag-level-2: [plan-eks plan-rds]Output Formats
File Output
terraci generate -o .gitlab-ci.ymlStdout
terraci generate # Prints to stdoutPipe to Other Tools
terraci generate | yq '.stages' # Extract stagesNext Steps
- Git Integration — Generate pipelines only for changed modules
- GitLab CI Configuration — Customize GitLab pipeline settings, images, and job defaults