Pipery Terraform CD#

Reusable GitHub Action for Terraform deployment with structured logging via Pipery.

GitHub Marketplace Version License: MIT

Table of Contents#

Quick Start#

name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pipery-dev/terraform-cd@v1.1.0
        with:
          project_path: .
          terraform_version: latest
          auto_approve: true

Pipeline Overview#

StepDescriptionSkip Input
PlanTerraform planskip_plan
ApplyTerraform applyskip_apply
Drift checkPost-apply plan for drift detectionskip_drift_check

Configuration Options#

NameDefaultDescription
project_path.Path to the Terraform root module.
config_file.pipery/config.yamlPath to Pipery config file.
terraform_versionlatestTerraform CLI version to use.
backend_config``Comma-separated backend config vars (key=val).
var_file``Path to a .tfvars file.
working_directory.Working directory for Terraform commands.
plan_onlyfalseOnly run plan, do not apply.
auto_approvetrueSkip interactive approval of plan.
destroyfalseRun terraform destroy instead of apply.
check_drifttrueRun post-apply plan to detect drift.
log_filepipery.jsonlPath to write the JSONL log file.
skip_planfalseSkip terraform plan step.
skip_applyfalseSkip terraform apply step.
skip_drift_checkfalseSkip drift detection step.

Usage Examples#

Example 1: Basic Terraform apply with auto-approve#

name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pipery-dev/terraform-cd@v1.1.0
        with:
          project_path: .
          terraform_version: latest
          auto_approve: true

Example 2: With backend configuration#

- uses: pipery-dev/terraform-cd@v1.1.0
  with:
    project_path: ./infrastructure
    terraform_version: 1.7
    backend_config: bucket=my-bucket,key=prod/terraform.tfstate,region=us-east-1
    auto_approve: true

Example 3: Using variables file#

- uses: pipery-dev/terraform-cd@v1.1.0
  with:
    project_path: .
    terraform_version: latest
    var_file: terraform.prod.tfvars
    auto_approve: true

Example 4: Plan-only dry run#

- uses: pipery-dev/terraform-cd@v1.1.0
  with:
    project_path: .
    terraform_version: latest
    plan_only: true

Example 5: Destroy infrastructure#

- uses: pipery-dev/terraform-cd@v1.1.0
  with:
    project_path: .
    terraform_version: latest
    destroy: true
    auto_approve: true

Example 6: Interactive approval with drift detection#

- uses: pipery-dev/terraform-cd@v1.1.0
  with:
    project_path: ./terraform/prod
    terraform_version: 1.6
    auto_approve: false
    check_drift: true
    backend_config: bucket=my-state-bucket,key=prod

GitLab CI#

Use the GitLab mirror template when .gitlab-ci.yml is published for this pipeline family. Import it from the mirrored GitLab project or use it as a reference implementation for running the same Pipery pipeline outside GitHub Actions.

The GitLab pipeline maps action inputs to CI/CD variables, publishes pipery.jsonl as an artifact, and maintains the same skip controls. Store credentials as protected GitLab CI/CD variables.

include:
  - project: pipery-dev/terraform-cd
    ref: v1.1.0
    file: /.gitlab-ci.yml

GitLab CI Variables#

Configure these protected variables in Settings > CI/CD > Variables:

  • TERRAFORM_VERSION - Terraform version (default: latest)
  • BACKEND_CONFIG - Backend configuration (key=val format)
  • VAR_FILE - Path to .tfvars file
  • AUTO_APPROVE - Auto-approve without prompt (default: true)

Bitbucket Pipelines#

Bitbucket Cloud pipelines provide an alternative to GitHub Actions. Use Bitbucket shared pipeline imports to reference the exported Pipery pipeline instead of copying YAML into every application repository.

Getting Started#

  1. Add a Bitbucket import source for the shared Pipery pipeline and import the exported pipeline by name:
definitions:
  imports:
    pipery-shared: pipery-dev/terraform-cd:v1.1.0
    pipery-custom: pipery-dev/terraform-cd:v1.1.0:.bitbucket/shared-pipelines.yml

pipelines:
  branches:
    main:
      import: pipery-terraform-cd@pipery-shared

  custom:
    run-pipery:
      import: pipery-terraform-cd@pipery-custom

Use {project-path}/{repo-slug}:{branch-or-tag} for a shared repository bitbucket-pipelines.yml, or {project-path}/{repo-slug}:{branch-or-tag}:{config-filepath} for another exported YAML file.

  1. Configure Protected Variables in Repository Settings > Pipelines > Repository Variables:
    • TERRAFORM_VERSION - Terraform version (default: latest)
    • BACKEND_CONFIG - Backend configuration variables
    • VAR_FILE - Path to .tfvars file
    • AUTO_APPROVE - Auto-approve (default: true)
  2. Commit to trigger deployment

Pipeline Stages#

The Bitbucket equivalent follows the same structure:

checkout → setup → plan → apply → drift_check → logs

Features#

  • Plan and apply infrastructure changes
  • Drift detection for configuration compliance
  • Remote backend state management
  • Variables file support
  • Interactive and auto-approved modes
  • Destroy capability
  • JSONL-based pipeline logging
  • 90-day log retention

About Pipery#

Pipery Pipery is an open-source CI/CD observability platform. Every step script runs under psh (Pipery Shell), which intercepts all commands and emits structured JSONL events — giving you full visibility into your pipeline without any manual instrumentation.

Development#

# Run the action locally against test-project/
pipery-actions test --repo .

# Regenerate docs
pipery-actions docs --repo .

# Dry-run release
pipery-actions release --repo . --dry-run