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.
Related
I am working on deploy isolated Azure Function App container on Azure App Service.
I have created App Service Plan:
"sku": {
"name": "P1v2",
"tier": "PremiumV2",
"size": "P1v2",
"family": "Pv2",
"capacity": 1
},
"kind": "linux",
with App Service:
"kind": "functionapp,linux,container"
I am using AzureWebAppContainer#1 task:
- task: AzureWebAppContainer#1
displayName: Deploy to app service
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
appName: my-web-app0name
imageName: myacr01.azurecr.io/myregistryname:tag01
configurationSettings: -linuxFxVersion DOCKER|myacr01.azurecr.io/myregistryname:tag01"
appSettings: ${{ parameters.appSettings }}
resourceGroupName: my-resource-group
When the task is executed by Azure DevOps yaml pipeline in the logs there is info that:
Trying to update App Service Configuration settings. Data: {"appCommandLine":null,"windowsFxVersion":"DOCKER|myacr01.azurecr.io/myregistryname:tag01"}
I do not understand why the windowsFxVersion is used instead of linuxFxVersion.
On resource level in Azure Portal I can also see that I have windowsFxVersion set instead of linuxFxVersion.
Worth to mention that when you are clicking thought the wizard on Azure Portal with default Function App it is set as linuxFxVersion.
This is not a valid value:
-linuxFxVersion DOCKER|myacr01.azurecr.io/myregistryname:tag01"
Please find available values by executing:
az webapp list-runtimes --os linux
Result:
[
"DOTNETCORE:7.0",
"DOTNETCORE:6.0",
"DOTNETCORE:3.1",
"NODE:16-lts",
"NODE:14-lts",
"PYTHON:3.9",
"PYTHON:3.8",
"PYTHON:3.7",
"PHP:8.0",
"PHP:7.4",
"RUBY:2.7",
"JAVA:17-java17",
"JAVA:11-java11",
"JAVA:8-jre8",
"JBOSSEAP:7-java11",
"JBOSSEAP:7-java8",
"TOMCAT:10.0-java17",
"TOMCAT:10.0-java11",
"TOMCAT:10.0-jre8",
"TOMCAT:9.0-java17",
"TOMCAT:9.0-java11",
"TOMCAT:9.0-jre8",
"TOMCAT:8.5-java11",
"TOMCAT:8.5-jre8"
]
I'm using in my current project:
linuxFxVersion: 'DOTNET|6.0'
netFrameworkVersion: 'v6.0'
kind: 'functionapp,linux'
Bicep for creating the app:
resource hostingPlan 'Microsoft.Web/serverfarms#2020-10-01' = {
name: hostingPlanName
location: location
kind: 'linux'
sku: {
name: hostingPlanNameSkuName
}
properties: {
reserved: true
}
}
resource myApp 'Microsoft.Web/sites#2020-06-01' = {
name: myAppName
location: location
kind: 'functionapp,linux'
identity: {
type: 'SystemAssigned'
}
properties: {
httpsOnly: true
serverFarmId: hostingPlan.id
clientAffinityEnabled: true
siteConfig: {
alwaysOn: true
netFrameworkVersion: 'v6.0'
linuxFxVersion: 'DOTNET|6.0'
ftpsState: 'Disabled'
cors: {
allowedOrigins: [
'*'
]
}
}
}
}
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'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) }}
---
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.