I will show how to create a branch policy that will run a CI pipeline to validate Terraform code along with a Terraform plan, during a Pull Request in Azure DevOps and will include the YAML CI Pipeline.
Branch policies help teams protect their important branches of development. Policies enforce your team’s code quality and change management standards.
docs.microsoft.com
Depending on how you create and test your Terraform code; you will probably be doing this type of test locally but during a pull-request it gives a piece of mind to the reviewer(s) that the Terraform pull-request has successfully been validated along with a plan that can be reviewed.
Note:- In a previous blog post I have detailed how to Deploy Terraform using Azure DevOps
Time to DevOps
In this blog post, I will be using branch:- Develop
Now to create a CI Pipeline that will be used to validate and plan Terraform code during a Pull Request
Select Pipelines -> New Pipeline in Azure DevOps
- Where is your code? Azure Repos Git
- Select your repository
- Select .yml basic and review the below .yml pipeline
Throughout the Pipeline, you will notice my reference to a Storage Account, Resource Group and container for the Terraform state file along with an Azure SPN – read my blog here on how to create these
backendServiceArm: 'tamopstf'
backendAzureRmResourceGroupName: 'tamopstf'
backendAzureRmStorageAccountName: 'tamopstf'
backendAzureRmContainerName: 'tfstatedevops'
backendAzureRmKey: 'terraform.tfstate'
In my Pipeline, I have two Stages
Validate:- To Validate my Terraform code, if validation fails the pipeline fails (consists of Terraform init & validate)
Plan:- if Validation is successful, it moves to next stage of pipeline which is planning the Terraform code to output a Terraform Plan that can be reviewed as part of the pull request. (consists of Terraform plan)
The below YAML Pipeline will validate and plan your Terraform code
name: $(BuildDefinitionName)_$(date:yyyyMMdd)$(rev:.r)
trigger: none
pr: none
stages :
- stage: validate
jobs:
- job: validate
continueOnError: false
steps:
- task: TerraformInstaller@0
displayName: 'install'
inputs:
terraformVersion: '0.12.3'
- task: TerraformTaskV1@0
displayName: 'init'
inputs:
provider: 'azurerm'
command: 'init'
backendServiceArm: 'tamopstf'
backendAzureRmResourceGroupName: 'tamopstf'
backendAzureRmStorageAccountName: 'tamopstf'
backendAzureRmContainerName: 'tfstatedevops'
backendAzureRmKey: 'terraform.tfstate'
- task: TerraformTaskV1@0
displayName: 'validate'
inputs:
provider: 'azurerm'
command: 'validate'
- stage: plan
dependsOn: [validate]
condition: succeeded('validate')
jobs:
- job: "Validate_TF_Develop_Branch"
steps:
- checkout: self
- task: TerraformInstaller@0
displayName: 'install'
inputs:
terraformVersion: '0.12.3'
- task: TerraformTaskV1@0
displayName: 'init'
inputs:
provider: 'azurerm'
command: 'init'
backendServiceArm: 'tamopstf'
backendAzureRmResourceGroupName: 'tamopstf'
backendAzureRmStorageAccountName: 'tamopstf'
backendAzureRmContainerName: 'tfstatedevops'
backendAzureRmKey: 'terraform.tfstate'
- task: TerraformTaskV1@0
displayName: 'plan'
inputs:
provider: 'azurerm'
command: 'plan'
environmentServiceNameAzureRM: 'tamopstf'
Now save the pipeline; you can rename and add to a specific folder as below prior to saving

Now you have a Pipeline ready to be part of your branch policy; once the pipeline has been configured in a branch policy, it can run automatically as part of the pull request process.
Apply Branch Policy
In Azure DevOps select Repos -> Branches and you will see a screen similar to below with your branches available.

In my example, I mentioned that I will be applying the branch policy to Develop.
Select … (to right of branch) -> Branch Policies
We will be creating a Build Validation; this is used to “Validate code by pre-merging and building pull request changes.”
Adding a build policy by selecting + on Build Validation
Below is the build policy I added
- Build pipeline:- Assign the pipeline that was created earlier in this blog post
- Trigger:- Automatic
- Policy requirement:- Required
- Build expiration:- Immediately when Develop is updated
- Display Name:- Accurate display name of the build validation

Test the Branch Policy
A branch policy has now been created along with a build pipeline to validate and plan your Terraform code.
Create a pull request to the Develop Branch
Reviewing the pull request you will see in the Overview section the CI Pipeline that was created

This Pipeline will run automatically and the Pull request cannot be approved until the pipeline has been successful.

Awesome! We have now configured a branch policy that will run a CI pipeline to validate and plan your Terraform code during a Pull Request.
This pipeline can be reviewed and the Terraform plan can be reviewed as part of the pull request.
The Pipeline as mentioned has two stages; select either to review further

Once this has been reviewed, the pull request can be approved into develop
Hi Thomas
is there a way to exclude below properties. Since i dont want to store the state file.
backendServiceArm: ‘tamopstf’
backendAzureRmResourceGroupName: ‘tamopstf’
backendAzureRmStorageAccountName: ‘tamopstf’
backendAzureRmContainerName: ‘tfstatedevops’
backendAzureRmKey: ‘terraform.tfstate’
Add a DeleteFiles task?
– task: DeleteFiles@1
displayName: ‘Remove unneeded files’
inputs:
contents: |
terraform.tfstate