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.
Workflow:
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).blob.core.windows.net/$(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
inputs:
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
inputs:
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
inputs:
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
inputs:
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
inputs:
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
inputs:
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
inputs:
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.