Azure DevOps integrates Terraform infrastructure as code through a dedicated extension published by Microsoft DevLabs. The extension adds native Terraform tasks to pipelines instead of requiring raw CLI commands in script tasks. Purpose-built tasks cover init, plan, validate and apply with built-in authentication for Azure, AWS, GCP and OCI providers. The extension addresses common pain points such as backend authentication configuration and provides workflow support for passing plan files between stages using pipeline artifacts.
The extension originates from the need for consistent IaC delivery on Microsoft hosted agents where organizations do not maintain the machines. Teams implementing more and more Infrastructure as Code leveraging Azure DevOps require tasks that integrate easily and improve the software development process. The problem statement centers on the growth in popularity of Azure DevOps Microsoft Hosted Agents and the need for ability to consistently deploy software on machines that organizations do not maintain and managed. A required capability is tasks to install and validate that required software for build and deployment is configured correctly on the hosted agent. An additional ask is functionality that easily integrates into ADO and provides a better overall developer experience.
The Azure DevOps Terraform Task implementation satisfies both requirements. Installing Terraform can be configured to a specific version passed in at build, ensuring the correct version of Terraform is installed on the Microsoft hosted agent. The extension guides users in the process of using Terraform to deploy infrastructure within Azure, Amazon Web Services and Google Cloud Platform.
Extension Origin and Scope
The repo contains the Azure DevOps Pipeline tasks for installing Terraform and running Terraform commands in a build or release pipeline. The goal of this extension is to guide the user in the process of using Terraform to deploy infrastructure within Azure, Amazon Web Services and Google Cloud Platform.
The extension is authored by Microsoft DevLabs. It is not supported by Microsoft. To report a problem with this extension, create an issue in this repository. The maintainers of this repository will review and respond to the issue. You can also report problems or share feedback about this extension on Developer Community Forum.
Extension Contributions
The extension contains the following contributions:
- Terraform tool installer - for installing Terraform if not installed on the build agent
- Terraform - for executing the core Terraform commands
- Amazon Web Services service connection - for creating a service connection for AWS to provide AWS credentials
- Google Cloud Platform service connection - for creating a service connection for GCP to provide GCP credentials
| Contribution | Purpose |
| Terraform tool installer | Installing Terraform if not installed on the build agent |
| Terraform | Executing the core Terraform commands |
| Amazon Web Services service connection | Creating a service connection for AWS to provide AWS credentials |
| Google Cloud Platform service connection | Creating a service connection for GCP to provide GCP credentials |
The tasks are capable of running on the following build agent operating systems:
- Windows
- MacOS
- Linux
Installation Paths
The extension is available from the Azure DevOps Marketplace. An organization administrator needs to install it.
- Go to the Azure DevOps Marketplace
- Search for "Terraform" by Microsoft DevLabs
- Click "Get it free"
- Select your organization and click "Install"
Alternatively, install it via the CLI:
az devops extension install \
--publisher-id "ms-devlabs" \
--extension-id "custom-terraform-tasks" \
--organization "https://dev.azure.com/myorg"
Once installed, the Terraform tasks appear in the pipeline task catalog for all projects in the organization. The marketplace installation path provides a graphical workflow for administrators who prefer UI navigation. The CLI path enables automation of extension provisioning across multiple organizations and supports DevOps teams that treat extension installation as infrastructure.
Service Connections for Provider Authentication
The Terraform extension uses Azure DevOps service connections for provider authentication. The extension helps with common pain points like configuring backend authentication and works with pipeline artifacts for passing plan files between stages.
The built-in authentication coverage includes Azure, AWS, GCP and OCI providers. Service connections provide a centralized mechanism for credential management, reducing the need to embed secrets in pipeline variables. This impacts security posture by enabling rotation and auditing through the Azure DevOps service connection framework.
The AWS service connection contribution creates a service connection for AWS to provide AWS credentials. The GCP service connection contribution creates a service connection for GCP to provide GCP credentials. These service connections integrate with Terraform tasks to supply provider credentials without manual export.
Core Tasks and Version Management
The Azure DevOps Terraform Task does both installation validation and integration. First installing Terraform can be configured to a specific version passed in at build.
parameters:
- name: terraformVersion
type: string
steps:
- task: ms-devlabs.custom-terraform-tasks.custom-terraform-installer-task.TerraformInstaller@0
displayName: install terraform
inputs:
terraformVersion: ${{ parameters.terraformVersion }}
This ensure that the correct version of Terraform is installed on the Microsoft hosted agent. Version pinning prevents drift between local development and CI execution. The installer task abstracts the download and path setup, which is critical on ephemeral hosted agents where Terraform is not preinstalled.
The Terraform task executes core Terraform commands. Native tasks replace raw CLI commands in script tasks with purpose-built tasks for init, plan, validate and apply.
Pipeline Patterns and Stage Design
Pipeline design frequently separates validation, planning and application into distinct stages with dependencies and conditions.
A typical plan stage is defined as:
- stage: Plan
displayName: 'Plan Terraform'
dependsOn: Validate
jobs:
- job: Plan
displayName: 'Create Terraform plan'
steps:
- checkout: self
- task: TerraformInstaller@1
displayName: 'Install Terraform'
inputs:
terraformVersion: '$(terraformVersion)'
- task: AzureCLI@2
displayName: 'Terraform plan'
inputs:
azureSubscription: '$(azureServiceConnection)'
addSpnToEnvironment: true
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
set -euo pipefail
export TF_IN_AUTOMATION=true
export ARM_USE_OIDC=true
export ARM_USE_AZUREAD=true
export ARM_OIDC_TOKEN="$idToken"
export ARM_CLIENT_ID="$servicePrincipalId"
export ARM_TENANT_ID="$tenantId"
export ARM_SUBSCRIPTION_ID="$(az account show --query id -o tsv)"
export ARM_OIDC_AZURE_SERVICE_CONNECTION_ID="$AZURESUBSCRIPTION_SERVICE_CONNECTION_ID"
cd "$(terraformWorkingDirectory)"
terraform init -input=false
terraform plan -input=false -lock-timeout=300s -out=tfplan -var-file=prod.tfvars
terraform show -no-color tfplan > tfplan.txt
mkdir -p "$(Build.ArtifactStagingDirectory)/terraform-plan"
cp tfplan "$(Build.ArtifactStagingDirectory)/terraform-plan/tfplan"
cp tfplan.txt "$(Build.ArtifactStagingDirectory)/terraform-plan/tfplan.txt"
- publish: '$(Build.ArtifactStagingDirectory)/terraform-plan'
artifact: 'terraform-plan'
displayName: 'Publish Terraform plan artifact'
The plan job checks out source, installs Terraform, then runs an AzureCLI task to execute Terraform plan with OIDC environment variables. The plan output is saved as an artifact for later stages.
- stage: Apply
displayName: 'Apply Terraform'
dependsOn: Plan
condition: and(succeeded(),
The apply stage depends on Plan and uses a success condition gate. Artifact passing enables plan files to be reviewed between stages, supporting approval workflows.
Validation and Formatting Steps
Validation steps verify Terraform configurations against best practices, policies and compliance requirements.
Use tools like:
terraform validate
to confirm syntax is correct,
terraform fmt
to validate formatting or call static analysis tools. The fmt -check -recursive command is commonly used early in pipelines.
fmt -check -recursive
terraform init -input=false
terraform validate
Including validation steps in pipelines verifies Terraform configurations against best practices, policies and compliance requirements using tools like terraform validate to confirm syntax is correct, terraform fmt to validate formatting or call static analysis tools.
The Validate stage example uses OIDC:
- task: AzureCLI@2
displayName: "Terraform Validate (OIDC)"
inputs:
azureSubscription: "Federated-Azure-Connection-$(System.TeamProject)"
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
terraform validate
The Plan stage with variables:
- task: AzureCLI@2
displayName: "Terraform Plan (OIDC)"
inputs:
azureSubscription: "Federated-Azure-Connection-$(System.TeamProject)"
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
terraform plan \
-var="environment=${{ parameters.environment }}" \
-var="location=${{ parameters.location }}" \
-var-file=environments/${{ parameters.location }}/${{ parameters.environment }}.tfvars
Parameter-driven var files enable environment-specific planning.
Apply Stage with Approval and State Management
Deployment stages often use deployment jobs with environments for approval.
```
- stage: Deploy
displayName: "Terraform Apply with Approval"
dependsOn: ValidateAndPlan
variables:
TFSTATEKEY: $[ stageDependencies.ValidateAndPlan.TerraformValidateAndPlan.outputs['SetTfstateKey.TFSTATEKEY'] ]
jobs:
- deployment: TerraformApply
displayName: "Terraform Apply with Approval"
environment: terraform-approval
strategy:
runOnce:
deploy:
steps:
Checkout the repository to access tfvars files
checkout: self
Use template for setup and init
template: templates/terraform-setup.yml
parameters:
tfstateKey: $(TFSTATE_KEY)Terraform Apply
task: AzureCLI@2
displayName: "Terraform Apply (OIDC)"
inputs:
azureSubscription: "Federated-Azure-Connection-$(System.TeamProject)"
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
if [ "${{ parameters.debugMode }}" == "True" ]; then
export TF_LOG=DEBUG
echo "Debug mode
```
The deployment job targets an environment named terraform-approval, enabling gated approvals. The TFSTATE_KEY variable is passed from a previous stage using stageDependencies outputs. The template reference shows reuse of terraform-setup.yml for init consistency.
OIDC Authentication Pattern
OIDC based authentication is used to avoid long-lived secrets. Environment variables set for Azure provider include:
export TF_IN_AUTOMATION=true
export ARM_USE_OIDC=true
export ARM_USE_AZUREAD=true
export ARM_OIDC_TOKEN="$idToken"
export ARM_CLIENT_ID="$servicePrincipalId"
export ARM_TENANT_ID="$tenantId"
export ARM_SUBSCRIPTION_ID="$(az account show --query id -o tsv)"
export ARM_OIDC_AZURE_SERVICE_CONNECTION_ID="$AZURESUBSCRIPTION_SERVICE_CONNECTION_ID"
These variables configure Terraform to use Azure DevOps federated credentials. The pattern aligns with security best practices for pipelines, including access control, role-based permissions and regular security reviews to mitigate risks associated with pipeline configurations and execution.
Monitoring, Logging and Error Handling
Utilize Azure DevOps pipeline features like logging commands and error-handling tasks. Monitor pipeline execution, performance metrics and resource usage to identify bottlenecks, optimize workflows and ensure the reliability of infrastructure deployments.
Applying security best practices to pipelines, including access control, role-based permissions and regular security reviews to mitigate risks associated with pipeline configurations and execution supports operational resilience.
Document pipeline configurations, deployment processes and infrastructure designs to facilitate collaboration, knowledge sharing and onboarding of team members.
Developer Experience Improvements
The Azure Terraform CLI task can greatly improve the experience when working with Terraform within ADO. Information previously available in the output of the tasks is moved to a new tab, allowing quick navigation to see changes. With the push to have business users release code, this is less daunting for someone without a technical background to look at.
The example shows Dev where no changes were detected and UAT environment where changes were detected. Presenting change summaries in a dedicated UI tab reduces cognitive load for reviewers.
Operating System Coverage
Tasks are capable of running on the following build agent operating systems:
- Windows
- MacOS
- Linux
Cross-platform support means pipelines can target self-hosted agents with different OS requirements without rewriting task definitions. The Terraform tool installer handles OS-specific binary selection.
Integration Considerations
The extension helps with common pain points like configuring backend authentication and works with pipeline artifacts for passing plan files between stages. The extension also helps with common pain points like configuring backend authentication and works with pipeline artifacts for passing plan files between stages.
Deploying Terraform resources with Spacelift is mentioned as an alternative for end-to-end secure GitOps approach. Terraform is really powerful, but to achieve an end-to-end secure GitOps approach, you need to use a product that can run your Terraform workflows.
Conclusion
The Microsoft DevLabs Terraform extension for Azure DevOps establishes a structured path for Infrastructure as Code delivery by replacing ad-hoc script tasks with purpose-built Terraform tasks for init, plan, validate and apply. The extension’s installation via Marketplace or CLI enables organization-wide availability, while service connections for Azure, AWS, GCP and OCI centralize credential management and reduce secret sprawl. Version-pinned installation through TerraformInstaller@0 guarantees consistent tooling on ephemeral Microsoft hosted agents, and artifact-based plan passing between Validate, Plan and Apply stages supports review gates and approval environments. OIDC environment variable patterns eliminate long-lived credentials and align pipeline execution with federated identity best practices. Validation steps using terraform validate and terraform fmt combined with logging, error handling and monitoring create observable pipelines that enforce policy and compliance. The cross-platform support for Windows, MacOS and Linux broadens agent compatibility, and the documented lack of official Microsoft support clarifies maintenance responsibility. Together these elements form a cohesive workflow that improves developer experience, enables business user review of change summaries and provides a foundation for secure, repeatable Terraform deployments within Azure DevOps.