Bicep and Azure DevOps: AVD Backend Deployment with Deployment Stacks

Hello everyone!

This blog is the second one in the series of deploying AVD with Bicep and Azure DevOps. You can find the last blog here. Today we are going to talk about the backend of AVD and the additional resources that can be combined when deploying the backend. There is an extra feature combined with this enrollment. This feature is called Deployment Stacks. This option gives extra flexibility when changing resources in Azure as one unity.


  • Azure subscription (Azure DevOps is free, but I will connect to Azure)
  • Contributor or Owner role on the subscription (less rights are possible, but take more time to setup)
  • Visual Studio Code (VSCode) (Feel free to use any coding tool you want)
  • Bicep extension in VSCode
  • Azure DevOps Service connection configured with Contributor and User Access Administrator access on the subscription. Follow this guide.
  • Azure Virtual Desktop service principal needs Desktop Virtualization Power On Off Contributor access on the subscription. Follow this guide.

Setting up the files

We are going to setup the deployment with Azure DevOps. Make sure you have a repo connected with VSCode or some other tool. Use the files from my github pagemoving2cloud/BiCepAVD at main · moving2cloud/moving2cloud ( Make sure to start with the backend files. Because session hosts will be discussed in the last blog of the series. The exact folder structure is also important, because all templates are linked in those directories. Make sure to check the files for changes needed for your environment.

Configure the pipeline

Now we have the files, so we can start with the pipeline. The file Backend.yaml is located in the pipelines/templates folder, this file will link with DeployBackend.yaml to load the configuration with the templates. It is important to change the parameters in this pipeline. The correct subscription name needs to be present, because it is possible that the service connection can manage multiple subscriptions. Change the resource group name to your needs. This group will be used to deploy all the resources.

trigger: none

  vmImage: "ubuntu-latest"

  - name: azureResourceManagerConnection
    value: BicepAVDSC

  - template: ../DeployBackend.yaml
      azureResourceManagerConnection: $(azureResourceManagerConnection)
      location: 'westeurope'
      resourceGroupName: 'rg-avd-pl-bicep-test'
      subscriptionName: 'Visual Studio Enterprise Subscription – MPN'
      stackName: 'm2cavdstackbackend'

The file DeployBackend.yaml has all the jobs and tasks defined. The task “Create Deployment Stack” will make the whole deployment connected as one stack and will be visible after the deployment.

  - name: azureResourceManagerConnection
    type: string
  - name: location
    type: string
  - name: resourceGroupName
    type: string
  - name: subscriptionName
    type: string
  - name: stackName
    type: string

  - stage: DeployBackendAVDresources
    displayName: Deploy Backend AVD Resouces
      - name: azureServiceConnection
        value: ${{ parameters.azureResourceManagerConnection }}
      - name: location
        value: ${{ parameters.location }}
      - name: templateFile
        value: "./mainbackend.bicep"
      - name: parameterFile
        value: "./parametersbackend.jsonc"
      - name: stackName
        value: ${{ parameters.stackName }}

      - job: DeployBackendAVD
          - task: AzureCLI@2
            displayName: "Deploy Backend AVD"
              azureSubscription: ${{ parameters.azureResourceManagerConnection }}
              scriptType: pscore
              scriptLocation: inlineScript
              inlineScript: |
                $guid = New-Guid
                az group create --name ${{ parameters.resourceGroupName }} --location ${{ parameters.location }} 
                $result = az deployment group create --resource-group ${{ parameters.resourceGroupName }} --template-file $(templateFile) --parameters $(parameterFile) --name "DeployBackend_$guid.guid" | ConvertFrom-Json
          - task: AzureCLI@2
            displayName: "Create Deployment Stack"
              scriptType: bash
              scriptLocation: inlineScript
              connectedServiceNameARM: ${{ parameters.azureResourceManagerConnection }}
              inlineScript: |
                az stack group create --name ${{ parameters.stackName }} --resource-group ${{ parameters.resourceGroupName }} --template-file $(templateFile) --parameters $(parameterFile) --action-on-unmanage 'detachAll' --deny-settings-mode 'none'

Starting the deployment

When the pipeline is created, we are going to deploy the resources in Azure. When you run the pipeline it will ask for permissionspermit the access and run your pipeline.

As you can see the deployment running in your DevOps environment. There are some warnings, some of the configuration settings could be better, but this is not necessary for a succeeded deployment.

After running for about 5 minutes. Everything is deployed. This makes it really easy to deploy your AVD backplane with additional resourcesChanging settings is also very easy with the deployment stacks in Azure.

Testing the deployment stacks

Now we are going to test the deployment stack. The stack is deployed during the pipeline. This is visible in your resource group.

When you click on the stack you will see all the resources connected with the stack.

Now we are going to change something in this deployment. We are going to change some of the parameters of this deployment. I want to change the maxSessionLimit parameter of the hostpool and the text of the rampDownNotificationMessage from the scalingplan. As you can see, the following items are deployed with these parameters.

When you change the parameters files with new values and save them to the repo. You can just rerun the pipeline, because the pipeline is configured properly to update settings in your AVD Backplane. Not everything is editable, but most settings can be adjusted.

After a successful run of the pipelineall the changes were made.

Here you see the changes in the Azure portal.

This is really some awesome stuff! You should really test this feature, because managing Azure resources is going to be a lot easier.

Final Thoughts

Creating this post was really a learning curve with Bicep and Azure DevOps. Because Bicep templates can be setup in many ways and a lot of writing has been done about Bicep, but changing the deployment with deployment stacks could really be a difference for your AVD environment. This blog will have a follow up for the session hosts, so this deployment can have a complete setup.



  • Mischa Sachse

    Mischa Sachse is one of the founders of the Cloud Experts Community. Would you like to join in the fun? Make sure to contact him via the mail button below or find out more about him on his personal website.

    View all posts

Leave a Reply

Your email address will not be published. Required fields are marked *