I've got a pipeline I've created that deploys some app settings to all our websites (multiple per file), and I'm trying to conditionally set a variable within the JSON structure without any sort of anti-patterns.
For conditional variables, all we have this syntax:
${{ if endsWith('EXISTING_STRING','MATCH_STRING') }}:
${{ else }}:
This syntax assumes that you're going to put the entirety of the string after condition, though. If my JSON structure is 50 lines long, I don't want to do that. Is there a way to do this without that cluttered code, whilst avoiding any sort of anti-patterns as well?
Here's the Azure Piplines Module:
- task: AzureAppServiceSettings#1
displayName: 'Deploy App Settings'
inputs:
azureSubscription: "${{ parameters.resource_group_name }}"
appName: "wz${{ parameters.default_environment }}"
resourceGroupName: "${{ parameters.resource_group_name }}"
appSettings: |
[
{
"name": "LaunchUrl",
"value": "False",
/* ^^^^
Value I want to be conditional based off:
if endsWith( parameters['default_environment'], 'matchString'
The resulting string also contains parameters.default_environment FYI
*/
"slotSetting": true
},
{
"name": "DisableFHIR",
"value": "False",
"slotSetting": true
},
...
Thanks
Putting conditionals inside a string literal is unfortunately not supported. However, one technique my team uses is define our JSON values as a string parameter and populate it with variables that are evaluated at runtime.
parameters:
- name: appSettings
type: string
default: |
'[
{
"name": "appSetting1",
"value": "$(appSetting1)",
"slotSetting": "true"
}
]'
Personally, I like to go one further and define them as a yaml parameter and then use the convertToJson expression. This avoids the potential for malformed JSON and I can also put comments in the YAML.
parameters:
- name: resource_group_name
type: string
- name: appSettings
type: object
default:
- name: 'LaunchUrl'
value: '$(launchUrl)'
slotSetting: true
- name: 'DisableFHIR'
value: 'false'
slotSetting: true
job:
variables:
${{ if endsWith('prd', parameters.resource_group_name) }}:
launchUrl: https://production.dot.com
${{ else }}:
launchUrl: http://somewhere.else.com
steps:
- task: AzureAppServiceSettings#1
inputs:
azureSubscription: "${{ parameters.resource_group_name }}"
appName: "wz${{ parameters.default_environment }}"
resourceGroupName: "${{ parameters.resource_group_name }}"
appSettings: ${{ convertToJson(parameters.appSettings) }}
Related
can we automatically create a pipeline for each new function thats created ie fully automate the lot? Im not sure if it possible and wondering if anyone has done or can point me to something that has a set by step pocess?
can we automatically create a pipeline for each new function thats
created ie fully automate the lot?
Yes, you can.
For the simplest situation, for example, this is the deployment pipeline on my side:
trigger:
- none
pool:
vmImage: ubuntu-latest
parameters:
- name: functionname
default: bowman0822
steps:
- task: DownloadBuildArtifacts#1
inputs:
buildType: 'specific'
project: 'xxx'
pipeline: 'xxx'
buildVersionToDownload: 'latest'
downloadType: 'single'
downloadPath: '$(System.ArtifactsDirectory)'
- script: |
dir
displayName: 'Run a multi-line script'
- task: AzureFunctionApp#1
inputs:
azureSubscription: 'testbowman_in_AAD'
appType: 'functionAppLinux'
appName: '${{parameters.functionname}}'
package: '$(System.DefaultWorkingDirectory)/azurefunction'
runtimeStack: 'PYTHON|3.9'
#key step see the below.
- task: PythonScript#0
inputs:
scriptSource: 'inline'
script: |
import requests
import json
org_name = "<The Organization Name>"
project_name = "<The Product Name>"
pipeline_name = "${{parameters.functionname}}"
pat = "<Your Personal Access Token>"
url = "https://dev.azure.com/"+org_name+"/"+project_name+"/_apis/build/definitions?api-version=5.0"
payload = json.dumps({
"name": ""+pipeline_name+"",
"Repository": {
"name": "functiontest",
"type": "TfsGit"
},
"Process": {
"phases": [
{
"name": "Agent job 1",
"refName": "Job_1",
"condition": "succeeded()",
"target": {
"executionOptions": {
"type": 0
},
"allowScriptsAuthAccessOption": False,
"type": 1
},
"jobAuthorizationScope": "project"
}
]
}
})
headers = {
'Authorization': 'Basic '+pat,
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
Successfully created on my side:
Please note that the above sample is the simplest situation, there is nothing in the created pipeline. If you want specific requirements in pipeline, I suggest you to first manually create a pipeline, and then use this API so that from the response you can know how the request structure of Create API should be.
The code above is based on this REST API:
https://learn.microsoft.com/en-us/rest/api/azure/devops/build/definitions/create?view=azure-devops-rest-5.0
By the way, if you want YAML definition, there should be additional step to push the YAML definition to your repo.
I'm trying to create an Azure DevOps pipeline for deploying Azure Blueprint. There are some fields in the parameters file(JSON) which I want to be configurable. How can I pass these values as pipeline variables and use them in the parameters file?
I tried defining a pipeline variable and reference it in the parameter file like this "$(var-name)", but it didn't work. Is there a way to solve this?
Below is my pipeline definition, I'm using AzureBlueprint extension for creating and assigning blueprint:
steps:
- task: CreateBlueprint#1
inputs:
azureSubscription: $(serviceConnection)
BlueprintName: $(blueprintName)
BlueprintPath: '$(blueprintPath)'
AlternateLocation: false
PublishBlueprint: true
- task: AssignBlueprint#1
inputs:
azureSubscription: $(serviceConnection)
AssignmentName: '$(blueprintName)-assignment'
BlueprintName: $(blueprintName)
ParametersFile: '$(blueprintPath)/assign.json'
SubscriptionID: $(subscriptionId)
Wait: true
Timeout: 500
and my parameters file:
"parameters":{
"organization" : {
"value": "xxxx"
},
"active-directory-domain-services_ad-domain-admin-password" : {
"reference": {
"keyVault": {
"id": "/subscriptions/xxxx/resourceGroups/xxxx/providers/Microsoft.KeyVault/vaults/xxxx"
},
"secretName": "xxxx"
}
},
"jumpbox_jumpbox-local-admin-password" : {
"reference": {
"keyVault": {
"id": "/subscriptions/xxxx/resourceGroups/xxxx/providers/Microsoft.KeyVault/vaults/xxxx"
},
"secretName": "xxxx"
}
},
"keyvault_ad-domain-admin-user-password" : {
"value" : "xxxx"
},
"keyvault_deployment-user-object-id" : {
"value" : "xxxx"
},
"keyvault_jumpbox-local-admin-user-password" : {
"value" : "xxxx"
}
}
Since the Tasks (CreateBlueprint and AssignBlueprint) you are using doesn't support overriding parameters, you have two options:
Use the Azure CLI az blueprint command to directly create and assign blueprints.
Change the parameters file bei either using JSON variable substitution or by using a small PowerShell script (see blow):
Sample:
$paramFile = Get-Content ./azuredeploy.parameters.json | ConvertFrom-Json
$paramFile.parameters.organization.value = "your-org-name"
$paramFile | ConvertTo-Json | Set-Content ./azuredeploy.parameters.json
Be aware that the Task you are using hasn't received an update within the last 17 months (here is the GitHub repository).
AssignBlueprint#1 doesn't support natively this. However you can modify assign.json using Json substitution
It comes down to having Azure Pipeline variables with a name like a path to a leaf in the json file which you want to teplace.
Here is an example:
variables:
Data.DebugMode: disabled
Data.DefaultConnection.ConnectionString: 'Data Source=(prodDB)\MSDB;AttachDbFilename=prod.mdf;'
Data.DBAccess.Users.0: Admin-3
Data.FeatureFlags.Preview.1.NewWelcomeMessage: AllAccounts
# Update appsettings.json via FileTransform task.
- task: FileTransform#1
displayName: 'File transformation: appsettings.json'
inputs:
folderPath: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip'
targetFiles: '**/appsettings.json'
fileType: json
Hi does anyone have any idea on why im getting this error:
Got service connection details for Azure App Service:'nsclassroomstudent-dgyn27h2dfoyo'
##[debug][POST]https://login.windows.net/***/oauth2/token/
##[debug][GET]https://management.azure.com/subscriptions/237bc9da-22ad-49ea-8411-6cf6a190c18f/resourceGroups/ClassroomInTheCloud/providers/Microsoft.Web/sites/nsclassroomstudent-dgyn27h2dfoyo/?api-version=2016-08-01
##[debug]Correlation ID from ARM api call response : c3eefa7c-9088-44f1-8dc8-dccd7a9f8c4c
##[debug]Processed: ##vso[task.logissue type=error;code=ResourceNotFound;]
##[debug]Deployment Failed with Error: Error: Failed to fetch App Service 'nsclassroomstudent-dgyn27h2dfoyo' details. Error: The Resource 'Microsoft.Web/sites/nsclassroomstudent-dgyn27h2dfoyo' under resource group 'ClassroomInTheCloud' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix (CODE: 404)
##[debug]task result: Failed
My code is attached, I have been through the microsoft Site: https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-app-service-settings?view=azure-devops
I have added the Connected Service Name to my YAML but I still get the error and im not sure what else it wants.
Thanks
#pool:
# vmImage: windows-latest
resources:
repositories:
- repository: Student
name: Classroom In The Cloud/Student
path:
- include: /Student/Student
type: git
ref: master #branch name
variables:
System.Debug: true
azureSubscription: 'azuresubscription'
RG: 'ClassroomInTheCloud'
Location: West Europe
containername: 'private'
appconnectionname: 'RunPipelinesInOtherSubscription'
jobs:
- job: job1
displayName: Create And Publish Artifact
pool:
vmImage: vs2017-win2016
steps:
- checkout: Student
clean: true
- task: DotNetCoreCLI#2
displayName: dotnet restore
inputs:
command: restore
projects: '**/*.csproj'
- task: DotNetCoreCLI#2
displayName: dotnet build
inputs:
projects: '**/*.csproj'
workingDirectory: Student
- task: DotNetCoreCLI#2
displayName: dotnet publish
inputs:
command: publish
projects: '**/*.csproj'
arguments: --output "$(Build.ArtifactStagingDirectory)"
zipAfterPublish: true
modifyOutputPath: false
workingDirectory: Student
- task: PublishPipelineArtifact#1
displayName: Publish Pipeline Artifact
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifact: 'Student'
publishLocation: 'pipeline'
- job: job2
displayName: 'Get Variable Value for Student Env'
dependsOn: job1
steps:
- task: AzureCLI#1
displayName: 'Azure CLI '
inputs:
azureSubscription: $(azureSubscription)
scriptLocation: inlineScript
inlineScript: |
mkdir $(Pipeline.Workspace)\BlobFile
az storage blob download --container-name $(containername) --file '$(Pipeline.Workspace)/s/student.json' --name 'student.json' --connection-string 'DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=devscriptstorage;AccountKeyMY VALUE HERE'
- pwsh: |
cd '/home/vsts/work/1/s/'
ls
$armOutput = Get-Content '/home/vsts/work/1/s/student.json' | convertfrom-json
$student = $armOutput.studentvalue #use student not studentvalue
$type = $armOutput.type
$appServicePlanName = $armOutput.appServiceValue
Write-Host "The value of [$student] is [$appServicePlanName]"
Write-Host "##vso[task.setvariable variable=studentvalue;isOutput=true]$student" #use studentvalue not $studentvalue
Write-Host "##vso[task.setvariable variable=appServiceValue;isOutput=true]$appServicePlanName" #use appServiceValue not $appServicePlanName
name: setvarStep
- script: echo $(setvarStep.studentvalue)
- script: echo $(sevarStep.appServiceValue)
name: echovar
- job: job3
displayName: Create Web App
dependsOn: job2
variables:
webappname: $[ dependencies.job2.outputs['setvarStep.studentvalue'] ]
appservice: $[ dependencies.job2.outputs['setvarStep.appServicevalue'] ]
# Download Artifact File
steps:
- download: none
- task: DownloadPipelineArtifact#2
displayName: 'Download Build Artifacts'
inputs:
patterns: '**/*.zip'
path: '$(Build.ArtifactStagingDirectory)'
# deploy to Azure Web App
- task: AzureWebApp#1
inputs:
package: $(Build.ArtifactStagingDirectory)/**/*.zip
azureSubscription: $(azureSubscription)
appName: '$(webappname)'
ResourceGroupName: $(RG)
- task: AzureAppServiceSettings#1
inputs:
azureSubscription: $(azureSubscription)
ConnectedServiceName: $(appconnectionname)
appName: '$(webappname)'
resourceGroupName: $(RG)
# To deploy the settings on a slot, provide slot name as below. By default, the settings would be applied to the actual Web App (Production slot)
# slotName: staging
appSettings: |
{
"name": "DIAGNOSTICS_AZUREBLOBCONTAINERSASURL",
"value": "VALUEINHERE",
"slotSetting": false
},
{
"name": "DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS",
"value": "365",
"slotSetting": false
},
{
"name": "OEM",
"value": "netsupport",
"slotSetting": false
},
{
"name": "SCM_REPOSITORY_PATH",
"value": "d:\\home\\respository",
"slotSetting": false
},
{
"name": "VIDEO_CLIENT_URL",
"value": "https://signal-uks.classroom.cloud",
"slotSetting": false
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "10.15.2",
"slotSetting": false
}
I ended up fixing this, when changing app settings on an app you have to put in the app name in the displayname area in the code like so:
- task: AzureAppServiceSettings#1
displayName: 'Azure Web App Deploy: $(webappname)'
inputs:
azureSubscription: $(azureSubscription)
ConnectedServiceName: $(appconnectionname)
appName: '$(webappname)'
resourceGroupName: $(RG)
# To deploy the settings on a slot, provide slot name as below. By default, the settings would be applied to the actual Web App (Production slot)
# slotName: staging
appSettings: |
{
"name": "DIAGNOSTICS_AZUREBLOBCONTAINERSASURL",
"value": "VALUEINHERE",
"slotSetting": false
},
{
"name": "DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS",
"value": "365",
"slotSetting": false
},
{
"name": "OEM",
"value": "netsupport",
"slotSetting": false
},
{
"name": "SCM_REPOSITORY_PATH",
"value": "d:\\home\\respository",
"slotSetting": false
},
{
"name": "VIDEO_CLIENT_URL",
"value": "https://signal-uks.classroom.cloud",
"slotSetting": false
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "10.15.2",
"slotSetting": false
}
I got to this conclusion after playing around with the classic pipeline editor and watching what it would do to the YAML code.
---
variables:
azureSubscription: 'Visual Studio Professional Subscription (237bc9da-22ad-49ea-8411-6cf6a190c18f)'
RG: ClassroomInTheCloud
jobs:
- job: 1
steps:
- task: AzureCLI#1
dislayName: 'Azure CLI '
inputs:
azureSubscription: $(azureSubscription)
scriptLocation: inlineScript
inlineScript: |
mkdir $(Pipeline.Workspace)\BlobFile
az storage blob download --container-name $(containername) --file '$(Pipeline.Workspace)/s/student.json' --name 'student.json' --connection-string 'VALUE IN HERE'
- pwsh: |
cd '/home/vsts/work/1/s/'
ls
$armOutput = Get-Content '/home/vsts/work/1/s/student.json' | convertfrom-json
$studentvalue = $armOutput.studentvalue
$type = $armOutput.type
Write-Host "The value of [$studentvalue] is [$type]"
Write-Output "##vso[task.setvariable variable=$studentvalue;]$type"
Write-Output "##vso[task.setvariable variable=$studentvalue;isOutput=true]$studentvalue"
Write-Output "The Value of studentvalue is [$studentvalue]"
name: setvarStep
- script: |
echo $(studentvalue)
- job: 2
displayName: Create Web App
dependsOn: 1
variables:
webappname: $[studentvalue]
steps:
- task: AzureWebApp#1
inputs:
azureSubscription: $(azureSubscription)
resourceGroupName: $(RG)
appName: $(webappname)
package: $(System.DefaultWorkingDirectory)**/*.csproj
- task: AzureAppServiceSettings#1
displayName: Azure App Service Settings
inputs:
azureSubscription: $(azureSubscription)
appName: $(webappname)
# To deploy the settings on a slot, provide slot name as below. By default, the settings would be applied to the actual Web App (Production slot)
# slotName: staging
appSettings: |
[
{
"name": "DIAGNOSTICS_AZUREBLOBCONTAINERSASURL",
"value": "VALUEINHERE",
"slotSetting": false
},
{
"name": "DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS",
"value": "365",
"slotSetting": false
},
{
"name": "OEM",
"value": "netsupport",
"slotSetting": false
},
{
"name": "SCM_REPOSITORY_PATH",
"value": "d:\\home\\respository",
"slotSetting": false
},
{
"name": "VIDEO_CLIENT_URL",
"value": "https://signal-uks.classroom.cloud",
"slotSetting": false
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "10.15.2",
"slotSetting": false
}
]
Can someone tell me why I am getting the following errors when putting this YAML file in the pipeline?
Line 14, Col 7: Unexpected Value Display Name
Line 45, Col 6: A sequence was not expected
Please firstly review this doc: YAML schema reference and Define variables, following is the sample yaml of setting a multi-job output variable.
jobs:
# Set an output variable from job A
- job: A
pool:
vmImage: 'vs2017-win2016'
steps:
- powershell: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the value"
name: setvarStep
- script: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable into job B
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-18.04'
variables:
myVarFromJobA: $[ dependencies.A.outputs['setvarStep.myOutputVar'] ] # map in the variable
# remember, expressions require single quotes
steps:
- script: echo $(myVarFromJobA)
name: echovar
Thus the following snippet of yaml should be correct syntax for your reference.
pool:
vmImage: windows-latest
variables:
azureSubscription: 'subscription here'
RG: 'WClassroomInTheCloud'
jobs:
- job: job1
steps:
- task: AzureCLI#1
displayName: 'Azure CLI '
inputs:
azureSubscription: $(azureSubscription)
scriptLocation: inlineScript
inlineScript: |
mkdir $(Pipeline.Workspace)\BlobFile
az storage blob download --container-name $(containername) --file '$(Pipeline.Workspace)/s/student.json' --name 'student.json' --connection-string 'VALUE IN HERE'
- pwsh: |
cd '/home/vsts/work/1/s/'
ls
$armOutput = Get-Content '/home/vsts/work/1/s/student.json' | convertfrom-json
$student = $armOutput.studentvalue #use student not studentvalue
$type = $armOutput.type
Write-Host "The value of [$student] is [$type]"
Write-Host "##vso[task.setvariable variable=studentvalue;isOutput=true]$student" #use studentvalue not $studentvalue
name: setvarStep
- script: echo $(setvarStep.studentvalue)
name: echovar
- job: job2
displayName: Create Web App
dependsOn: job1
variables:
webappname: $[ dependencies.job1.outputs['setvarStep.studentvalue'] ]
steps:
- task: AzureWebApp#1
inputs:
azureSubscription: $(azureSubscription)
appType: 'webApp'
resourceGroupName: $(RG)
appName: $(webappname)
package: $(System.DefaultWorkingDirectory)**/*.csproj
- task: AzureAppServiceSettings#1
inputs:
azureSubscription: $(azureSubscription)
appName: $(webappname)
resourceGroupName: $(RG)
# To deploy the settings on a slot, provide slot name as below. By default, the settings would be applied to the actual Web App (Production slot)
# slotName: staging
appSettings: |
{
"name": "DIAGNOSTICS_AZUREBLOBCONTAINERSASURL",
"value": "VALUEINHERE",
"slotSetting": false
},
{
"name": "DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS",
"value": "365",
"slotSetting": false
},
{
"name": "OEM",
"value": "netsupport",
"slotSetting": false
},
{
"name": "SCM_REPOSITORY_PATH",
"value": "d:\\home\\respository",
"slotSetting": false
},
{
"name": "VIDEO_CLIENT_URL",
"value": "https://signal-uks.classroom.cloud",
"slotSetting": false
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "10.15.2",
"slotSetting": false
}
The second error is because steps at line 40 is at the level of webappname when it should be at the level of variables. Generally you shouldn't use single-space indentation to avoid such errors.
I am not sure about the first error but try writing displayName instead of dislayName on line 10.
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?
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.