Later edit:
I maintain a global template file azuredeploy.parameters.json.template with placeholders. Here are some of the params, including the one - ipFilter - I'm having issues with. If I don't use this parameter, it passes the validation and the deployment works correctly:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"resourceGroupName": {
"value": "rg-mine-<%= $environment %>"
},
"location": {
"value": "westeurope"
},
"environment": {
"value": "<%= $environment %>"
},
"ipFilter": {
"value": <%= (ConvertTo-Json $ipFilter) %>
},
"buildSuffix": {
"value": {
"name": "",
"number": ""
}
},
"serverFarm": {
"value": {
"name": "asp-landscape-<%= $environment %>",
"resourceGroup": "rg-landscape-<%= $environment %>",
"resourceType": "Microsoft.Web/serverFarms"
}
}
....
other params
}
}
A PS script (Build-TemplateParameterFiles) reads the global template, merges in the env file as a hashtable, renders via Invoke‑EpsTemplate, and writes out the final azuredeploy.parameters.<env>.json:
function Build-TemplateParameterFiles {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[string]$Location,
[Parameter(Mandatory = $true)]
[object[]]$Environments
)
$templateFileName = 'azuredeploy.parameters.json.template'
$templateFileText = [System.IO.File]::ReadAllText($Location + $templateFileName)
Write-Host "Start building parameter files ..."
foreach ($environment in $Environments) {
$parameterFileName = 'azuredeploy.parameters.' + $environment + '.json'
Write-Host "Building $parameterFileName ..."
$parameterObject = Get-Content $($Location + $parameterFileName) -Raw `
| ConvertFrom-Json -AsHashtable
$parameterObject += @{ environment = $environment }
Invoke-EpsTemplate -Template $templateFileText -Binding $parameterObject -Safe `
| Set-Content $($Location + $parameterFileName)
Write-Host "$parameterFileName Build!"
}
Write-Host "Done building parameter files!"
}
Export-ModuleMember -Function Build-TemplateParameterFiles
For each environment (e.g., dvlp), the powershell script generates I have another JSON file that contains just the environment‑specific values. For dvlp, I'll have azuredeploy.parameters.dvlp.json. I've added a step in the pipeline to print out the file after the step that builds the template file, and right before moving to the validation template step. Here's what it looks like:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"resourceGroupName": {
"value": "rg-mine-dvlp"
},
"location": {
"value": "westeurope"
},
"ipFilter": {
"value": ["123", "123"]
},
"environment": {
"value": "dvlp"
},
"buildSuffix": {
"value": {
"name": "",
"number": ""
}
},
"serverFarm": {
"value": {
"name": "asp-landscape-dvlp",
"resourceGroup": "rg-landscape-dvlp",
"resourceType": "Microsoft.Web/serverFarms"
}
}
}
}
Then, this gets validated in the pipeline by the default task Azure DevOps provides when designing/editing a new pipeline. Here's the step:
- task: AzureResourceManagerTemplateDeployment@3
displayName: "Validate ARM Templates"
inputs:
deploymentScope: "Subscription"
azureResourceManagerConnection: "$(azureServiceConnectionDvlp)"
subscriptionId: "$(subscriptionIdDvlp)"
location: $(DEFAULT_LOCATION)
csmFile: $(rootDirectory)/templates/azuredeploy.json
csmParametersFile: $(rootDirectory)/templates/azuredeploy.parameters.dvlp.json
deploymentMode: Validation
overrideParameters: >
-buildSuffix { "name": "$(Build.DefinitionName)", "number": "$(Build.BuildNumber)" }
And here's where the problem arises and sticks. I always get the following exception, no matter the combination of raw vs escaped tags, quoting, indexing ($ipFilter['allowedIps'] vs $ipFilter.allowedIps vs $ipFilter.value):
##[error]Error: Ensure the Parameters file ('…azuredeploy.parameters.dvlp.json') is valid. Task failed while parsing with the following error: Expected double-quoted property name in JSON at position 2312
I also thought that perhaps ipFilter is a reserved keyword and replace it with just abc, but the exception persists.
What am I missing here? One challenge: I cannot change the pipeline nor the PS script that builds the params file, as these are consistent across the entire project/all repos.