Azure Deployment – Multi Cloud Deployment on Azure and Azure DevOps using Infrastructure as Code with Terraform.

In our previous lab (See), we have learn how to deploy purely on Azure using ARM/Bicep, which is a powerful tools with one crucial disadvantage. ARM and Bicep only works for Azure. But when dealing with large solution it is not uncommon to have multiple providers involve even if you decide to stick solely to the Microsoft universe.

So let’s take our case to the next level. Our Storage Account Explorer was a big hit, we got at least 5 users right from the start and the number is likely to grow.

The management was quite impressed by Infrastructure as Code. Your team and you are now entrusted with the mission to bring Infrastructure as Code to every new feature project. Even the project setup is meant to be done by Infrastructure as Code. The idea is: if a new PoC project got approved, the respective team just need to run the „script“ and a new DevOps project is created along with a few resources on Azure. This should ease and speed up the deployment process for new projects significantly.

In this exercise, we will create a new Azure DevOps project and a storage account using Terraform. Please mind! Althought Azure DevOps and Azure Cloud are both from Microsoft, they are independent services and consider different cloud solution. We could also deploy some AWS, Google Cloud or other resources here.

Task 1: Setup project

  1. Open  to open the cloudshell in fullscreen mode.
  2. Switch to Bash.
  3. Now let’s setup our new Terraform project.
mkdir terraform
cd terraform
code .

Task 2: Setup Azure provider

  1. Setup azurerm provider in to access Azure capabilities
terraform {
  required_providers { 
    azurerm = {
      source = "hashicorp/azurerm"
      version = ">=2.77.0"

# Configure the Microsoft Azure Provider 
provider "azurerm" { 
  features {} 

Task 3: Adding Azure resources

  1. Now that the provider are setup, we can start adding Azure resources in our script. The designated file is
  2. You can find the complete solution below. But try to come up with your own. Here are a few things that you may find useful:
    3. Terraform does not offer a uniqueString function like ARM/Bicep. But you can use random_string (docs) provider instead.
  3. Run terraform init at the root of your project folder `/terraform/`  to initialize the providers.
  4. Run terraform plan -out tf.tfplan to create an execution plan.
  5. Run terraform apply tf.tfplan to apply the changes in the plan.
  6. Try to modify the script so that it enable the static_website service (see Docs).
  7. Repeat step 5 and 6.
resource "azurerm_resource_group" "draphony" {
    name        = "azlab-iac-tf"
    location    = "westeurope"

resource "random_string" "draphony" {
    keepers {
      rgid =
    length      = 13
    special     = false
    upper       = false

resource "azurerm_storage_account" "draphony" {
    name                        = "draphony${}"
    location                    = azurerm_resource_group.draphony.location
    account_replication_type    = "LRS"
    account_tier                = "Standard"
    resource_group_name         =

Bonus: Modify the so that it outputs the keys from the storage account

Task 4: Adding Azure DevOps resources to your Terraform project

Please mind that you need an Azure DevOps account for this part. You can create a free account here.

  1. As with Azure, we need to setup the Azure DevOps provider to work with Azure DevOps.
  2. Go to your Terraform project folder and open
  3. Modify the content of the file by adding the Azure DevOps provider to the required_providers and add and new provider block for azuredevops as shown below:
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=2.77.0"
    azuredevops = {
      source = "microsoft/azuredevops"
      version = ">=0.1.0"

provider "azurerm" {
  features {}
provider "azuredevops" {
  personal_access_token = "TO_BE_REPLACED"
  org_service_url       = "TO_BE_REPLACED"
  1. Go to Azure DevOps and acquire a PAT with full scope and the org_service_url and replace it in the
  2. Go back to your project and open and write the Terraform script, which should deploy:
    1. a new Azure DevOps project Awesome Project (See doc)
    2. an additional Uninitialized git repository webapp (See doc)
    3. All repositories should only allow commits from authors from „“ and „“.
  3. Run terraform plan -out tf.tfplan to create an execution plan.
  4. Run terraform apply tf.tfplan to apply the changes.
resource "azuredevops_project" "draphony" {
  name               = "Awesome Project"
  description        = "You did it man!"
  visibility         = "private"
  version_control    = "Git"
  work_item_template = "Scrum"

resource "azuredevops_git_repository" "draphony" {
  project_id     =
  name           = "webapp"

  initialization {
    init_type = "Clean"

resource "azuredevops_repository_policy_author_email_pattern" "draphony" {
  project_id            =
  enabled               = true
  blocking              = true
  author_email_patterns = ["*", "*"]

Bonus: Modify the and so users can create a configurable amount of repos.

Task 5: Clean up

  1. Run terraform destroy at the root of your project folder `/terraform/` to tear down everything.

Tác giả

  • Azure

Newsletter zu Aktionen

Trage dich ein um keine Aktionen von uns zu verpassen.
Wir senden 1-2 E-Mails pro Quartal.