terrawatch

command module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2026 License: MIT Imports: 1 Imported by: 0

README

terrawatch

Catch Terraform drift before it causes an incident.

terrawatch runs terraform plan on your stacks on a schedule, and when real infrastructure no longer matches your code, it automatically opens a pull request — so your team can review and fix it.

No servers. No Kubernetes. Drop it into any existing CI pipeline in minutes.


The problem it solves

Your Terraform code says one thing. Your cloud says another.

This happens constantly — someone clicks in the console, a resource auto-scales, a tag gets added manually. Without drift detection, you won't notice until a terraform apply surprises you in production.

terrawatch runs in the background, checks continuously, and brings the diff to your PR queue where your team already works.


How it works

Every few hours (scheduled CI job)
  └── terraform plan on each stack
        ├── No changes → silent, nothing happens
        └── Changes found → opens a PR with the full plan diff

The PR looks like this:

[terrawatch] Drift detected in stack: production

Stack:     production
Path:      ./environments/prod
Detected:  Sun, 27 Apr 2026 06:00:00 UTC

Summary
| Add | Change | Destroy |
|  0  |   1    |    0    |

# aws_instance.web will be updated in-place
~ instance_type = "t3.small" → "t3.medium"

If an open drift PR already exists for a stack, terrawatch skips it — no duplicate PRs.


Install

Homebrew (Mac / Linux):

brew tap MaripeddiSupraj/terrawatch
brew install terrawatch

curl (Linux / Mac):

# Linux (amd64)
curl -sSL https://github.com/MaripeddiSupraj/terrawatch/releases/latest/download/terrawatch_linux_amd64.tar.gz | tar xz
sudo mv terrawatch /usr/local/bin/

# Mac (Apple Silicon)
curl -sSL https://github.com/MaripeddiSupraj/terrawatch/releases/latest/download/terrawatch_darwin_arm64.tar.gz | tar xz
sudo mv terrawatch /usr/local/bin/

Go:

go install github.com/MaripeddiSupraj/terrawatch@latest

Try it immediately

No config file needed. Just run it in any Terraform directory:

cd infra/production
terrawatch detect

Or scan everything at once:

terrawatch detect --recursive ./infra

Output:

  terrawatch v0.1.0

  no config file — local mode (dry-run)

  Scanning 3 stack(s)

  ✓  vpc                  no drift
  ⚠  eks                  drift detected  +1 ~0 -0
  ✓  rds                  no drift

  ──────────────────────────────────────────────────
  3 scanned  ·  1 drifted  ·  2 clean

Local mode is always a dry-run — it prints results and exits. No PR is opened without a config file.


Set up automated PR creation

1. Create terrawatch.yaml in your repo root:

stacks:
  - name: production
    path: ./environments/prod
    vars_file: prod.tfvars     # optional
  - name: staging
    path: ./environments/staging

github:
  repo: your-org/your-infra-repo
  base_branch: main
  labels: [drift, infra]

For GitLab:

stacks:
  - name: production
    path: ./environments/prod

gitlab:
  repo: your-group/your-project
  base_branch: main
  labels: [drift]

2. Run:

# see drift without opening a PR
GITHUB_TOKEN=xxx terrawatch detect --dry-run

# full run — opens a PR for each drifted stack
GITHUB_TOKEN=xxx terrawatch detect

Add to an existing pipeline

GitHub Actions — scheduled drift detection

Drop this into your infra repo. It runs every 6 hours and can be triggered manually.

# .github/workflows/drift-detect.yml
name: Drift Detection
on:
  schedule:
    - cron: "0 */6 * * *"
  workflow_dispatch:
    inputs:
      dry_run:
        type: boolean
        default: false

jobs:
  detect:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ${{ vars.AWS_REGION }}

      - name: Install terrawatch
        run: |
          curl -sSL https://github.com/MaripeddiSupraj/terrawatch/releases/latest/download/terrawatch_linux_amd64.tar.gz | tar xz
          sudo mv terrawatch /usr/local/bin/

      - name: Detect drift
        run: terrawatch detect --config terrawatch.yaml
        env:
          GITHUB_TOKEN: ${{ secrets.TERRAWATCH_PAT }}

Required secrets:

Secret What it is
TERRAWATCH_PAT GitHub PAT with repo scope — for opening PRs
AWS_ROLE_ARN IAM role ARN for OIDC auth (no stored keys needed)

Tip: Use a dedicated PAT instead of the built-in GITHUB_TOKEN. The built-in token requires a blanket repo setting to create PRs — a PAT keeps permissions explicit.

Add as a post-apply check

Run after terraform apply to confirm the apply fully converged:

- name: Apply
  run: terraform apply -auto-approve tfplan

- name: Verify convergence
  run: terrawatch detect --dry-run --config terrawatch.yaml
  # exits 1 if drift still present → fails the pipeline
GitLab CI
drift-detect:
  stage: monitor
  only:
    - schedules
  script:
    - terrawatch detect --config terrawatch.yaml
  variables:
    GITLAB_TOKEN: $MY_GITLAB_PAT

CLI reference

terrawatch detect [dir...]        check current dir or specified paths
terrawatch detect --recursive     walk all subdirs for terraform stacks
terrawatch detect --dry-run       print drift, do not open a PR
terrawatch detect --config        use a config file (enables PR creation)
terrawatch version                print version info

Exit codes:

Code Meaning
0 No drift detected
1 Drift found, or an error occurred

This makes it safe to use in scripts:

terrawatch detect && echo "all clean" || pagerduty-alert

Configuration reference

stacks:
  - name: string           # display name for this stack
    path: string           # path to the terraform root module
    vars_file: string      # optional .tfvars file
    backend_config:        # optional backend key/value overrides
      key: value

# Use either github OR gitlab — not both

github:
  token: string            # or set GITHUB_TOKEN env var
  repo: owner/repo         # required
  base_branch: main        # default: main
  labels: []               # PR labels
  assignees: []            # GitHub usernames

gitlab:
  token: string            # or set GITLAB_TOKEN env var
  repo: group/project      # required
  url: https://gitlab.com  # for self-hosted GitLab
  base_branch: main        # default: main
  labels: []               # MR labels
  assignees: []            # GitLab usernames

terraform:
  bin_path: terraform      # path to terraform binary if not on PATH

Why not Atlantis or tf-controller?

Atlantis tf-controller terrawatch
Requires a running server Yes Yes (needs K8s) No
Detects drift automatically No No Yes
Opens a PR/MR on drift Yes (on PR only) No Yes
GitHub + GitLab GitHub only No Yes
Stored cloud credentials Yes Yes No (OIDC)

terrawatch is not trying to replace Atlantis. It fills the gap: automatic drift detection with no infrastructure to run.


License

MIT — see LICENSE

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
ui
pkg

Jump to

Keyboard shortcuts

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