Repository navigation
Azure DevOps Pipelines
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.
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-runTo 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 tf-snag tab splits findings into Drift, Deprecations and Pending changes, each with its count.

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
.tffile 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.
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| 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 |
Start here
How it works
Integrations
Project