Azure Pipelines Guide

TFGaurd in Azure Pipelines:
CI Terraform Security Setup

A complete azure-pipelines.yml with multi-stage security gates, fail-on-violation configuration, and Azure DevOps branch policy integration.

April 6, 2026 TFGaurd Team 12 min read Azure Pipelines · DevSecOps · Consideration

Azure Pipelines powers infrastructure deployments for some of the world's largest enterprises — and it's exactly where a terraform security tool for CI like TFGaurd has the highest leverage.

This guide provides a production-ready azure-pipelines.yml with multi-stage design: Terraform init, plan generation, TFGaurd security scan, and optional apply. Each stage feeds into the next, ensuring security is never skipped.

Enterprise Note: TFGaurd is fully compatible with Azure DevOps self-hosted agents running on Windows (PowerShell) and Linux (bash). No internet access required beyond fetching the TFGaurd binary on first install.

Complete azure-pipelines.yml

YAML — azure-pipelines.yml # ── TFGaurd Terraform Security Pipeline ─────────────────────────── trigger: branches: include: - main - develop pr: branches: include: - main variables: TF_VERSION: '1.7.5' TF_WORKING_DIR: '$(System.DefaultWorkingDirectory)/infra' TFGAURD_FAIL_ON: 'high' stages: # ── Stage 1: Validate ────────────────────────────────────────────── - stage: Validate displayName: 'Terraform Validate' jobs: - job: TF_Validate pool: vmImage: 'ubuntu-latest' steps: - task: TerraformInstaller@1 inputs: terraformVersion: $(TF_VERSION) - script: | cd $(TF_WORKING_DIR) terraform init -backend=false terraform validate displayName: 'Validate HCL Syntax' # ── Stage 2: Plan ────────────────────────────────────────────────── - stage: Plan displayName: 'Terraform Plan → JSON' dependsOn: Validate jobs: - job: TF_Plan pool: vmImage: 'ubuntu-latest' steps: - task: TerraformInstaller@1 inputs: terraformVersion: $(TF_VERSION) - script: | cd $(TF_WORKING_DIR) terraform init -backend=false terraform plan -out=tfplan -input=false terraform show -json tfplan > tfplan.json displayName: 'Generate Plan JSON' env: ARM_CLIENT_ID: $(ARM_CLIENT_ID) ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) ARM_TENANT_ID: $(ARM_TENANT_ID) ARM_SUBSCRIPTION_ID: $(ARM_SUBSCRIPTION_ID) - task: PublishPipelineArtifact@1 inputs: targetPath: '$(TF_WORKING_DIR)/tfplan.json' artifact: 'terraform-plan' # ── Stage 3: TFGaurd Security Scan ──────────────────────────────── - stage: Security displayName: 'TFGaurd Security Scan' dependsOn: Plan jobs: - job: TFGaurd_Scan pool: vmImage: 'ubuntu-latest' steps: - task: DownloadPipelineArtifact@2 inputs: artifact: 'terraform-plan' targetPath: '$(Pipeline.Workspace)/plan' - script: | curl -sSL https://tfgaurd.com/install.sh | bash tfgaurd scan --file $(Pipeline.Workspace)/plan/tfplan.json \ --fail-on $(TFGAURD_FAIL_ON) --output json > tfgaurd-report.json displayName: 'Run TFGaurd Security Scan' env: TFGAURD_API_KEY: $(TFGAURD_API_KEY) - task: PublishPipelineArtifact@1 condition: always() inputs: targetPath: 'tfgaurd-report.json' artifact: 'tfgaurd-security-report' # ── Stage 4: Apply (manual approval gate) ───────────────────────── - stage: Apply displayName: 'Terraform Apply' dependsOn: Security condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) jobs: - deployment: TF_Apply environment: production # configure approval gates on this environment pool: vmImage: 'ubuntu-latest' strategy: runOnce: deploy: steps: - script: | cd $(TF_WORKING_DIR) terraform apply -auto-approve displayName: 'Apply Terraform Changes'

Setting Up Azure DevOps Variable Groups

Store secrets in Pipelines → Library → Variable Groups. Link the group to your pipeline using the group: key:

YAML — Pipeline Variable Group variables: - group: terraform-security-secrets # contains ARM_* and TFGAURD_API_KEY - name: TFGAURD_FAIL_ON value: high

Variables in the group to configure:

  • ARM_CLIENT_ID, ARM_CLIENT_SECRET, ARM_TENANT_ID, ARM_SUBSCRIPTION_ID — Azure credentials
  • TFGAURD_API_KEY — Optional; unlocks premium multi-cloud rules

Enforcing Branch Policies

To block PRs with security violations from being completed, enable the Build Validation branch policy in Repos → Branches → Branch Policies → Build Validation. Select your TFGaurd pipeline as a required status check.

Enterprise Tip: In Azure DevOps, you can also add a Required Reviewer to the Security stage — meaning a security engineer must approve the scan results before apply proceeds. This creates a dual gate: automated + human.

Secure Your Azure DevOps Pipeline

TFGaurd integrates with Azure Pipelines in minutes. Free for AWS teams. Premium unlocks Azure, GCP, and Oracle rules.

Start Free Trial