How to use Azure DevOps to publish cloud service extended support
Published Nov 23 2022 11:12 PM 4,422 Views

Azure cloud service extended support(CSES) is a new Azure Resource Manager based deployment model for Azure Cloud Services product. Cloud Services (extended support) has the primary benefit of providing regional resiliency along with feature parity with Azure Cloud Services deployed using Azure Service Manager. It also offers some ARM capabilities such as role-based access and control (RBAC), tags, policy, and supports deployment templates. 


For the classic cloud service, we have Azure DevOps built-in pipeline task Azure Cloud Service Deployment task - Azure Pipelines | Microsoft Learn to help us manage the CI/CD progress easily and the task for CSES is not ready yet. In this blog, I have a brief guide on how to use the Azure ARM template to create or update the CSES deployment. 


The main points are like below. 


  • Define couple of variables for the storage account to prepare the ARM template deployment. 
  • Use the VSBuild@1 to build the cloud service project and output the cloud service package file or configuration file. 
  • Use built in task AzureFileCopy@5 to upload a build directory to the blob storage.
  • Using the storage reference including the access key to generate a SAS token by AzurePowerShell@5, and output to variable which will be used in the next task.
  • Using the output of previous task and utilize the value for the ARM template deployment task AzureResourceManagerTemplateDeployment@3




1. Firstly, we can create a starter pipeline and need to prepare the upload to the storage account. The variables below can help on the further operation below.


stg_account       <the name of storage account>

stg_key              <access key of storage account>

stg_container    <container name of storage account>

stg_prefix          $[format('{0:yyyyMMddHHmm}', pipeline.startTime)]        

stg_url               https://$(stg_account)$(stg_container)

cscfg_name       <name of configuration file>

cspkg_name      <name of package file>

url_cscfg            $(stg_url)/$(stg_prefix)/$(cscfg_name)

url_cspkg           $(stg_url)/$(stg_prefix)/$(cspkg_name)  




2. Use the Visual studio build task to build your task based on your cloud service project solution file and output to the local path on the agent.




#Build you project under your repository
#1. restore the NuGet dependency
- task: NuGetCommand@2
    command: 'restore'
    restoreSolution: '**/*.sln'
    feedsToUse: 'select'
    vstsFeed: xxx

#2. Use MS build to output cloud service project configuration and package to the local agent temporary location
- task: VSBuild@1
    solution: '**\*.sln'
    msbuildArgs: '/t:Publish /p:DeployOnBuild=true /p:AutomatedBuild=True /p:configuration=release /p:TargetProfile=Cloud /p:PublishDir=%SYSTEM_DEFAULTWORKINGDIRECTORY%/Debug/publish'

#3. Copy configuration and package file to the local path on the agent where any artifacts locate to
- task: CopyFiles@2
    SourceFolder: 'Debug/publish'
    Contents: '**'
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

#3. Copy definition file to the local path on the agent where any artifacts locate to
- task: CopyFiles@2
    SourceFolder: 'Project'
    Contents: '*.csdef'
    TargetFolder: '$(Build.ArtifactStagingDirectory)'



For more detail, reference to document MSBuild - MSBuild | Microsoft Learn.


3. Use the pipeline task Azure File Copy to upload configuration, definition and package file of cloud service. (Azure File Copy task - Azure Pipelines | Microsoft Learn). The task supports authentication based on Azure Active Directory. Authentication using a service principal and managed identity are available. You can assign the permission Contributor and Storage Blob Data Contributor to allow the access of service connection. (Service connections in Azure Pipelines - Azure Pipelines | Microsoft Learn)


Find the service principle in the project setting:





YAML version of File copy:


# Upload the cloud service via Azure File Copy
- task: AzureFileCopy@5
    SourcePath: ‘$(Build.ArtifactsStagingDirectory) /*'        # you can set $(Build.ArtifactsStagingDirectory) as Build part for output of
    azureSubscription: xxx                                     # the name of service connector
    Destination: 'AzureBlob'
    storage: $(stg_account)                                    # variable stg_account
    ContainerName: $(stg_container)                            # variable stg_container
    BlobPrefix: $(stg_prefix)                                  # variable stg prefix is $[format('{0:yyyyMMddHHmm}', pipeline.startTime)]
    AdditionalArgumentsForBlobCopy: '--recursive'              # recursively copy the files in this directory



After copying the file, you will see the cloud service package copied in the storage.



4. Use the Azure powershell pipeline task to generate a temporary SAS token for 5 minutes


# Generate temp SAS token for 5 mins
- task: AzurePowerShell@5                                                     # please make sure the Azure Powershell which contain the module of Az and AzureRm
  name: GenerateSasToken
    azureSubscription: xxx                                                    # the name of service connector
    ScriptType: 'InlineScript'
    Inline: |
      $account_name = ${env:STG_ACCOUNT}
      $account_key = ${env:STG_KEY}
      $context = New-AzStorageContext -StorageAccountName $account_name -StorageAccountKey $account_key
      $sas = New-AzStorageAccountSASToken -Service Blob -ResourceType Service,Container,Object -Permission "rl" -ExpiryTime (Get-Date).AddMinutes(5) -Context $context
      $cspkg = ${env:URL_CSPKG} + $sas
      $cscfg = ${env:URL_CSCFG} + $sas
      Write-Host ("##vso[task.setvariable variable=cspkg]$cspkg")             # output $cspkg in powershell to global variable cspkg
      Write-Host ("##vso[task.setvariable variable=cscfg]$cscfg")             # output $cscfg in powershell to global variable cscfg
    azurePowerShellVersion: 'LatestVersion'



5. Use the ARM template pipeline task to deploy the CSES deployment. The sample template is referring to cloud-services-extended-support/101-cses-multirole-rdp at main · Azure-Samples/cloud-services-extend...


#Azure Resource Manager template deployment
- task: AzureResourceManagerTemplateDeployment@3                               
    deploymentScope: 'Resource Group'                                           # resource group level deployment
    azureResourceManagerConnection: xxx                                         # the name of service connector
    subscriptionId: xxx                                                         # subscription id of the service connector
    action: 'Create Or Update Resource Group'
    resourceGroupName: 'rg-002'                                                                               
    location: 'Australia Central'
    templateLocation: 'Linked artifact'
    csmFile: 'Template/CSES.template.json'
    csmParametersFile: 'Template/CSES.parameter.json'
    overrideParameters: '-packageSasUri $(cspkg) -configurationSasUri $(cscfg) -cloudServiceName cses4test002 -deploymentLabel deploy$(stg_prefix)' # overwrite some parameters of template.
    deploymentMode: 'Incremental'    



6. After deployment, you should see the task result like below and the cloud service with the tag below. You can update the code and configuration to make update to the current deployment.



In the Azure portal, you can find the deployment result in the cloud service resource group.



The deployment label should be the same as your defined timestamp.   



Version history
Last update:
‎Nov 12 2022 10:43 PM
Updated by: