Skip to content

Azure DevOps Pipelines

Wes Key edited this page Sep 14, 2026 · 2 revisions

There are two ways to run tf-snag in Azure Pipelines: with the tf-snag extension, which does the wiring for you, or with the CLI in a script step.

With the extension

The extension adds two tasks and a tf-snag tab on each pipeline run:

Task Does
tf-snag-install@0 downloads the CLI from the latest stable GitHub release, or a version you pin, and puts it on PATH
tf-snag@0 runs every check, attaches the report to the run tab, keeps the baseline for next time, and optionally raises work items, posts to Teams and updates the wiki
- script: |
    terraform -chdir=terraform plan -out tfplan -json > plan.jsonl
    terraform -chdir=terraform show -json tfplan > plan.json
  displayName: Terraform plan

- task: tf-snag-install@0

- task: tf-snag@0
  inputs:
    planLogDir: terraform            # the plan ran with -chdir=terraform
    teamsWebhook: $(teamsWebhook)    # secret variable; unset posts nothing
    workItems: dry-run

To track findings across runs, download the previous run's tf-snag artifact to $(Pipeline.Workspace)/prev before the drift step. The task reads prev/tf-snag.sarif there as its baseline by default, and publishes this run's reports as the artifact for the next one. The full scheduled pipeline, and every task input, is in the task documentation.

Drift marks the run succeeded with issues, not failed. A tool or plan error still fails it.

The run tab

The tf-snag tab splits findings into Drift, Deprecations and Pending changes, each with its count.

The tf-snag tab's Drift view: a summary banner, then each drifted resource with a link to its .tf file, an Update badge and how long ago it was first seen

Every finding shows:

  • its attribute changes, or the deprecation's detail and locations
  • a new badge or its first-seen age, with a baseline
  • a link to the .tf file declaring it, in Azure Repos or GitHub, with -source
  • a link to its work item, when one tracks it
  • ignored findings in their own collapsed group, with the reason

The tab follows the organisation's light or dark theme. It reads a run attachment of type tf-snag.report, so any step that attaches tf-snag's JSON lights it up, including a plain script step.

With the CLI only

No extension needed: run tf-snag once per report, then once more for the console log and the exit code.

- script: |
    terraform -chdir=terraform plan -out tfplan -json | tee plan.jsonl
    terraform -chdir=terraform show -json tfplan > plan.json

    ./tf-snag -check all -plan plan.json -plan-log plan.jsonl -plan-log-dir terraform \
      -format markdown -exit-code=false > tf-snag.md
    ./tf-snag -check all -plan plan.json -plan-log plan.jsonl -plan-log-dir terraform \
      -format sarif -source "$(Build.SourcesDirectory)" -exit-code=false > tf-snag.sarif
    echo "##vso[task.uploadsummary]$PWD/tf-snag.md"

    # console output and the exit code
    ./tf-snag -check all -plan plan.json -plan-log plan.jsonl -plan-log-dir terraform
  displayName: Detect drift

- task: PublishBuildArtifacts@1
  condition: succeededOrFailed()
  inputs:
    PathtoPublish: tf-snag.sarif
    ArtifactName: CodeAnalysisLogs

Where results can go

Surface CLI tf-snag@0 input Needs
tf-snag tab -format json + ##vso[task.addattachment type=tf-snag.report] publishAttachment (on) the extension installed
Summary tab -format markdown + ##vso[task.uploadsummary] publishSummary nothing
Scans tab -format sarif as the CodeAnalysisLogs artifact publishScansTab the SARIF SAST Scans Tab extension
Tests tab -format junit + PublishTestResults@2 nothing. Drift only
Boards -ado-url workItems see Work Items
Wiki -wiki-page wikiPage see Exceptions Register
Teams -teams-webhook teamsWebhook see Microsoft Teams

Clone this wiki locally