Back to selected work

DeployCompare

Follow the stack that broke from the pattern.

I built DeployCompare to tell infrastructure engineers whether a Terraform deploy on main looks routine or deserves a closer look, without changing their CI workflow.

Terraform comparisonacme-infra-platform
Synthetic demo
data-platformNew destroy class
Baseline confidence High
Baseline 1+1 ~1Within pattern
Baseline 2+1Within pattern
Baseline 3+1Within pattern
Baseline 4+1 ~2Within pattern
Baseline 5+1 ~1Within pattern
Baseline 6+1Within pattern
Candidate+2 ~2 -3 R1Investigate
What changed
Three destroys and one replacement appeared together.
Why it surfaced
The action mix broke from six recent successful runs.
Evidence
New destroy class · replacement risk · above P90.

Terraform plan files are precise. The go/no-go decision still isn't.

Terraform can describe every add, change, destroy, and replacement in a plan file. It cannot determine whether that mix is routine for this stack.

Reviewing a plan meant rebuilding that history by hand: which jobs belonged to the same stack, which successful runs made a fair baseline, and whether a destroy was new or something this pipeline does every week.

Terraform action counts show the size of a plan, but they do not show whether those actions are unusual for the stack. A large, repeatable update may be routine. A smaller plan can still introduce the first destroy or replacement seen in recent successful runs.

A diff showed magnitude
It did not show what this stack normally does.
CI preserved runs
It did not assemble those runs into a comparison baseline.
Logs held evidence
GitLab and GitHub each bury it in a different log format.
Review stayed manual
Someone still had to decide which stack to open first.

Normal is a history, not a hunch.

DeployCompare compares one candidate pipeline with recent successful runs for the same source and stack variant. It ranks the stacks by how far they drift from that history, so the review starts at the one that moved.

  1. 1Candidate

    The Terraform plan that needs review.

  2. 2Baseline

    Recent successful runs from the same comparison scope.

  3. 3Variant

    Every stack gets its own history, not a shared threshold.

  4. 4Evidence

    Deviation, confidence, and exact CI context explain the verdict.

DeployCompare reads Terraform plan JSON when the pipeline saves it, because structured change data needs no guessing. When there is no artifact, it parses the log text instead.

Summary, anomaly grid, then evidence.

The interface follows the order of an infrastructure review: learn whether anything is unusual, find the stack that caused the signal, then inspect the history behind it.

Stacks 3Outliers 1Baseline HighAssessment 1 / 3

Start with the comparison overview.

The summary counts the stack variants that changed, the ones that fall outside their own pattern, and how much history stands behind the call, before anyone opens a single metric.

data-platform20.57app-services0.45network0.45

Order stack variants by deviation.

Stack variants that differ most from their own historical baseline rise to the top, instead of remaining in the arbitrary order their CI jobs ran.

Candidate+2 ~2 -3 R1New destroy classExact CI job

Keep the verdict attached to proof.

Every verdict links back to the runs it came from, the resource groups that changed, and the CI job that produced the plan.

The hard part was finding the right history without crawling everything.

A broad crawl wastes provider requests, follows irrelevant jobs, and repeatedly analyzes the same baselines.

DeployCompare narrows the search at each step. It discovers related CI work, ranks likely Terraform sources using parser evidence, keeps that choice correctable, and collects only the history needed for the selected comparison scope.

  1. 1Discover the pipeline

    Start from the candidate pipeline the engineer is reviewing.

  2. 2Index job families

    Group recurring CI work before fetching historical logs.

  3. 3Rank Terraform candidates

    Test likely families against parser evidence, not job names alone.

  4. 4Confirm or override

    Keep automatic source selection visible and correctable.

  5. 5Crawl selected history

    Follow matching branch or release patterns through queued work.

  6. 6Reuse parsed evidence

    Reuse normalized jobs and preserve short-lived comparison context.

Bounded discovery
Candidate ranking starts from one resolved pipeline instead of searching the full project history or trusting job names.
Provider-safe collection
SQS absorbs matching history work at a rate GitLab and GitHub can sustain, avoiding bursts and irrelevant log fetches.
Parse once, reuse the record
A baseline that appears in ten comparisons is fetched and parsed once. Short-lived snapshots hold the active comparison together.

I tested it against decoy jobs, competing candidates, missing artifacts, malformed timestamps, canceled runs, young baselines, and destructive-change spikes.

Qualified results build trust.

The difficult part was not assigning a score. It was qualifying that score with source selection, parser quality, comparison scope, and baseline strength, then keeping those limits attached to the evidence.

So every verdict carries a baseline rating next to it. A confident-looking score drawn from three runs of history is worth less than a hedged one that admits it only has three.

Built with: React, Vite, Apollo Client, GraphQL Yoga, AWS Lambda, DynamoDB, SQS, Terraform, CloudFront, and GitLab CI with AWS OIDC.