Blog Post

ITOps Talk Blog
3 MIN READ

How to use Terraform to Create Azure DevOps Projects

chrisjeffreyuk's avatar
Aug 11, 2020

With the recent release by HashiCorp and Microsoft of the Azure DevOps Provider 0.0.1 for Terraform we look at how to use these new features to create repeatable standardized projects into Azure DevOps.

 

Introduction.

In this article we are going to look at the new Terraform Provider for Azure DevOps. Firstly, lets provide some useful links:

 

 

At the time of authoring this article the provider is at version 0.0.1. Functionality is still a little limited and some of the documentation needs more detail, but all the basics are there.

 

So What Can I Do With This?

One question that has been asked many times is "Can I automate and template Azure DevOps Projects?". Well, the answer is now yes.

 

The Terraform Azure DevOps Provider allows us to be able to create a standard Terraform deployment that creates a Project inside a DevOps Organization. We can use the resources to then describe what features we want enabled, disabled, or configured.

 

I have created a sample GitHub repo that holds the code examples we are going to look at below.

 

Ok, So Let's Get Started.

Like many others, I tend to break my Terraform files up into smaller sub files to make things a little easier to navigate. In the GitHub Repo I have five .tf files:

 

  • main.tf 
  • variables.tf (used to set my var. options cleanly)
  • outputs.tf
  • ado_repository.tf (we will cover this in more detail in the article)
  • github_service_connection.tf (we will use this to setup a connection to the GitHub Repo)

 

I'm not going to cover what all of the files do in this article (there are some great blog posts out there already for that), but if you are interested in getting a detailed understanding of Terraform I recommend you check out our very own Adin Ermie.

 

Let's start by looking at the main.tf file. The first area to note is that we need to define the org_service_url for Azure DevOps and personal_access_token we are going to use within the Provider Block.

 

The Organization Service URL is just the address to your DevOps org, for example https://dev.azure.com/myorg 

 

Have a look at the following Microsoft document for detailed steps on how to setup a Personal Access Token in Azure DevOps. 

 

main.tf

 

 

 

 

 

 

provider "azuredevops" {
  version = ">= 0.0.1"
  # Remember to specify the org service url and personal access token details below
  org_service_url = "xxxxxxxxxxxxxxxxxxxx"
  personal_access_token = "xxxxxxxxxxxxxxxxxxxx"
}

resource "azuredevops_project" "terraform_ado_project" {
  project_name       = var.project_name
  description        = var.description
  visibility         = var.visibility
  version_control    = var.version_control
  work_item_template = var.work_item_template
  # Enable or desiable the DevOps fetures below (enabled / disabled)
  features = {
      "boards" = "enabled"
      "repositories" = "enabled"
      "pipelines" = "enabled"
      "testplans" = "enabled"
      "artifacts" = "enabled"
  }
}

 

 

 

 

 

 

 

The rest of the arguments here are self-explanatory. we provide the basic options to setup the project and select to enable or disable the feature we require.

 

Next, we will look at the github_service_connection.tf. What we are doing here is defining a service connection into GitHub using GitHub Personal Access Tokens. Configuring GitHub PATs is documented here.

 

github_service_connection.tf

 

 

 

 

 

 

resource "azuredevops_serviceendpoint_github" "serviceendpoint_github" {
  project_id            = azuredevops_project.terraform_ado_project.id
  service_endpoint_name = "Sample GithHub Personal Access Token"

  auth_personal {
    # Also can be set with AZDO_GITHUB_SERVICE_CONNECTION_PAT environment variable
    personal_access_token = "xxxxxxxxxxxxxxxxxxxx"
  }
}

 

 

 

 

 

 

 

Finally, I am using an outputs.tf to return the newly created Project ID and Project URL.

 

outputs.tf

 

 

 

 

 

 

output "Project_ID" {
  value = azuredevops_project.terraform_ado_project.id
}

output "Project_URL" {
  value = azuredevops_project.terraform_ado_project.id
}

 

 

 

 

 

 

 

A Note About Repos.

Something that has been noted by a few people is that the Import option on the azuredevops_git_repository resource does not seem to work. Although documented as Import being a supported option (for public repos only at this time), it returns an error message. 

 

Demo

Here is a quick demo of the code in action.

 

Wrap Up!

So thats it! A straightforward way to create Azure DevOps Projects within your Organization, simple and repeatable.

Updated Aug 11, 2020
Version 2.0

4 Comments

  • Salam_ELIAS's avatar
    Salam_ELIAS
    Brass Contributor

    Hi Chris, can we apply this to Azure Devops server on-prem? If yes, what is needed to be done? Thanks in advance

  • Great post! This guide on using Terraform to create Azure DevOps projects is incredibly helpful for automating project setup and maintaining consistency across environments. The practical examples and clarity in your explanation really make it easier for teams to adopt Infrastructure as Code within Azure.

    It also ties in well with another article I recently read: https://vocal.media/journal/mastering-terraform-dev-ops-a-comprehensive-guide, which goes even deeper into best practices, state management, and structuring your Terraform code for scalability in DevOps workflows. Combining insights from both really gives a full picture—from initial setup to long-term infrastructure management.

     

    Thanks for sharing valuable content—looking forward to more posts like this!

  • ByronScottJones's avatar
    ByronScottJones
    Copper Contributor

    output "Project_URL" {

      value = azuredevops_project.terraform_ado_project.id

    }

     

    Should that be:

    azuredevops_project.terraform_ado_project.url