Getting Started

Get tfplan2md running in minutes with Docker, or integrate it into your CI/CD pipeline.

Installation

Choose your preferred installation method

🐳 Docker (Recommended)

The easiest way to get started. Docker automatically pulls the image when you run it.

Run directly
terraform show -json plan.tfplan | docker run -i oocx/tfplan2md

✅ Benefits: One command to run, no setup required, works everywhere Docker runs

⚙️ From Source

Build from source if you need the latest development version or want to contribute.

Clone and build
git clone https://github.com/oocx/tfplan2md.git
cd tfplan2md
dotnet build

📝 Requirements: .NET 10 SDK

Quick Start

Generate your first Markdown report in seconds

1

Create a Terraform Plan

terraform plan -out=plan.tfplan
2

Convert to JSON

terraform show -json plan.tfplan > plan.json
3

Generate Markdown Report

cat plan.json | docker run -i oocx/tfplan2md > plan.md

Common Usage Patterns

Pipe directly from Terraform

terraform show -json plan.tfplan | docker run -i oocx/tfplan2md

Read from file with mounted volume

docker run -v $(pwd):/data oocx/tfplan2md /data/plan.json

Write output to file

terraform show -json plan.tfplan | \
  docker run -i -v $(pwd):/data oocx/tfplan2md --output /data/plan.md

Generate summary-only report

terraform show -json plan.tfplan | \
  docker run -i oocx/tfplan2md --template summary

CI/CD Integration

Automatically post Terraform plan reports to your pull requests

GitHub Actions Workflow

Add this job to your workflow to automatically comment on PRs with Terraform plans.

.github/workflows/terraform.yml
name: Terraform Plan

on:
  pull_request:
    paths:
      - 'terraform/**'

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.9.0
      
      - name: Terraform Init
        run: terraform init
        working-directory: ./terraform
      
      - name: Terraform Plan
        run: terraform plan -out=plan.tfplan
        working-directory: ./terraform
      
      - name: Convert plan to JSON
        run: terraform show -json plan.tfplan > plan.json
        working-directory: ./terraform
      
      - name: Generate markdown report
        run: |
          docker run -v $(pwd):/data oocx/tfplan2md \
            /data/plan.json --output /data/plan.md
        working-directory: ./terraform
      
      - name: Post PR comment
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const plan = fs.readFileSync('terraform/plan.md', 'utf8');
            
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: plan
            });

Azure Pipelines Configuration

Use this pipeline template to post Terraform plans to Azure DevOps pull requests.

azure-pipelines.yml
trigger: none

pr:
  branches:
    include:
      - main
  paths:
    include:
      - terraform/*

pool:
  vmImage: 'ubuntu-latest'

steps:
  - task: TerraformInstaller@1
    inputs:
      terraformVersion: '1.9.0'
  
  - script: terraform init
    displayName: 'Terraform Init'
    workingDirectory: terraform
  
  - script: terraform plan -out=plan.tfplan
    displayName: 'Terraform Plan'
    workingDirectory: terraform
  
  - script: terraform show -json plan.tfplan > plan.json
    displayName: 'Convert to JSON'
    workingDirectory: terraform
  
  - script: |
      docker run -v $(pwd):/data oocx/tfplan2md \
        /data/plan.json --output /data/plan.md
    displayName: 'Generate markdown report'
    workingDirectory: terraform
  
  - bash: |
      MARKDOWN=$(cat terraform/plan.md)
      URL="$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/git/repositories/$(Build.Repository.ID)/pullRequests/$(System.PullRequest.PullRequestId)/threads?api-version=7.0"
      
      BODY=$(jq -n \
        --arg content "$MARKDOWN" \
        '{comments: [{content: $content, commentType: 1}], status: 1}')
      
      curl -X POST "$URL" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(System.AccessToken)" \
        -d "$BODY"
    displayName: 'Post PR comment'

GitLab CI Configuration

Configure GitLab CI to post Terraform plans as merge request comments.

.gitlab-ci.yml
terraform-plan:
  stage: plan
  image: hashicorp/terraform:1.9
  only:
    - merge_requests
  script:
    - cd terraform
    - terraform init
    - terraform plan -out=plan.tfplan
    - terraform show -json plan.tfplan > plan.json
    
    - |
      docker run -v $(pwd):/data oocx/tfplan2md \
        /data/plan.json --output /data/plan.md
    
    - |
      MARKDOWN=$(cat plan.md)
      curl --request POST \
        --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
        --header "Content-Type: application/json" \
        --data "{\"body\": \"$MARKDOWN\"}" \
        "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"

Note: Create a GitLab access token with api scope and add it as GITLAB_TOKEN in CI/CD variables.

Next Steps