2
votes

I am deploying a Resource Group from an Azure DevOps Build pipeline so that the release pipeline can deploy the rest of the resources as needed. Yes, I am deploying at the subscription level, and the resource group creates with no problem. My issue is that when I look at the "Export Template" option in the Azure Resource Manager, my changes are not represented, most notably my contentVersion is not updated, however, I also have noticed that the $schema is not the same either. Here is my resource group template:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "[parameters('semVer')]",
    "parameters": {
        "semVer": {
            "type": "string"
        },
        "resourceGroupName": {
            "type": "string"
        }
    },
    "resources": [
        {
            "name": "[parameters('resourceGroupName')]",
            "type": "Microsoft.Resources/resourceGroups",
            "apiVersion": "2019-05-01",
            "location": "eastus",
            "tags": {
            },
            "properties": {
            }
        }
    ],
    "outputs": {
    },
    "functions": [
    ]
}

and here is my parameters file that I am using:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "semVer":{
            "value": "0.0.0.1"
        },
        "resourceGroupName":{
            "value": "rgName"
        }
    }
}

As I said, I want to update the content version, so I am using a transform in my build pipeline that should update the contentVersion to the Assembly Semantic Version. I seems like the transform is working, here is my azure-pipelines.yml:

name: $(date:yyyyMMdd)$(rev:.r)-$(Build.SourceBranchName)-$(GitVersion.SemVer)

trigger:
  - master
  - develop

stages:
- stage: DEV
  displayName: 'DEV'
  condition: and(always(), contains(variables['Build.SourceBranch'], 'develop'))
  pool:
    vmImage: 'ubuntu-latest'
  variables:
    contentVersion: $(GitVersion.AssemblySemVer)
    parameters.semVer.value: $(GitVersion.AssemblySemVer)
    parameters.resourceGroupName.value: 'rgName-DEV'
  jobs:
    - job: DevResourceGroup
      steps:
      - task: GitVersion@5
        inputs:
          preferBundledVersion: false
          updateAssemblyInfo: true
          configFilePath: './GitVersion.yml'
      - script: echo %Action%%BuildVersion%
        displayName: 'Set Build Number to Semantic Version'
        env:
          Action: '##vso[build.updatebuildnumber]'
          BuildVersion: '$(GitVersion.SemVer)'
      - task: FileTransform@2
        inputs:
          folderPath: '$(Build.SourcesDirectory)'
          xmlTransformationRules: 
          jsonTargetFiles: './ResourceGroup/resourceGroup.parameters.json'
      - task: AzureResourceManagerTemplateDeployment@3
        inputs:
          deploymentScope: 'Subscription'
          azureResourceManagerConnection: 'ConnectionName'
          subscriptionId: 'GUID'
          location: 'East US'
          templateLocation: 'Linked artifact'
          csmFile: '$(Build.SourcesDirectory)/ResourceGroup/resourceGroup.json'
          csmParametersFile: '$(Build.SourcesDirectory)/ResourceGroup/resourceGroup.parameters.json'
          deploymentMode: 'Incremental'
      - task: PublishBuildArtifacts@1
        inputs:
          PathtoPublish: '$(Build.SourcesDirectory)'
          ArtifactName: 'develop'
          publishLocation: 'Container'

- stage: PROD
  displayName: 'PROD'
  condition: and(always(), contains(variables['Build.SourceBranch'],'master'))
  pool:
    vmImage: 'ubuntu-latest'
  variables:
    contentVersion: $(GitVersion.AssemblySemVer)
    parameters.semVer.value: $(GitVersion.AssemblySemVer)
  jobs:
    - job: ProdResourceGroup
      steps:
      - task: GitVersion@5
        inputs:
          preferBundledVersion: false
          updateAssemblyInfo: true
          configFilePath: './GitVersion.yml'
      - script: echo %Action%%BuildVersion%
        displayName: 'Set Build Number to Semantic Version'
        env:
          Action: '##vso[build.updatebuildnumber]'
          BuildVersion: '$(GitVersion.SemVer)'
      - task: FileTransform@2
        inputs:
          folderPath: '$(Build.SourcesDirectory)'
          xmlTransformationRules: 
          jsonTargetFiles: './ResourceGroup/resourceGroup.parameters.json'
      - task: AzureResourceManagerTemplateDeployment@3
        inputs:
          deploymentScope: 'Subscription'
          azureResourceManagerConnection: 'ConnectionName'
          subscriptionId: 'GUID'
          location: 'East US'
          templateLocation: 'Linked artifact'
          csmFile: '$(Build.SourcesDirectory)/ResourceGroup/resourceGroup.json'
          csmParametersFile: '$(Build.SourcesDirectory)/ResourceGroup/resourceGroup.parameters.json'
          deploymentMode: 'Incremental'
      - task: PublishBuildArtifacts@1
        inputs:
          PathtoPublish: '$(Build.SourcesDirectory)'
          ArtifactName: 'master'
          publishLocation: 'Container'

It appears that the transform works just fine because the resource group in DEV does have the DEV text appended. The step in the pipeline also outputs the following:

Applying JSON variable substitution for ./ResourceGroup/resourceGroup.parameters.json
Applying JSON variable substitution for /home/vsts/work/1/s/ResourceGroup/resourceGroup.parameters.json
Substituting value on key contentVersion with (string) value: 0.1.0.0
Substituting value on key value with (string) value: 0.1.0.0
Substituting value on key value with (string) value: rgName-DEV
JSON variable substitution applied successfully.

My concern is that when I go to Export the template from the Azure Resource Manager, the template looks as such:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {},
    "resources": []
}

Why is my contentVersion returned to the default at this point in time? How would I verify what version of my template was deployed to an environment? What is the point of the contentVersion variable if it is just going to be overwritten?

1
Exactly my point. I want to be able to see the contentVersion that I apply in my pipeline and be able to see it in Azure. Did you figure out a better approach? Using tags maybe or something else to version infrastructure in Azure.Oliver Nilsen
I have not found a better solution, other than to use an IAC solution like Terraform and track versions of my infrastructure there.BigDevJames

1 Answers

0
votes

I'd say both the content version and schema do not matter at all when you are deploying the template. besides, exporting the template has nothing to do with verifying it works.

Exporting the template is a way to get your current resources configuration (kinda), if you just deployed a template it makes no sense to export the template, because if the template worked - your configuration was applied successfully.