如何将Azure PowerShell任务的数组参数传递到ARM模板
问题根因
- Azure DevOps流水线的输出变量如果值为
[开头的数组JSON,会被自动解析为数组对象,直接引用时会丢失外层方括号,转为逗号分隔的元素字符串 ConvertTo-Json默认深度为2,Key Vault访问策略的嵌套结构会被截断,导致生成的JSON不完整,这也是你单独校验打印值合法、但实际传递后解析失败的核心原因之一- 当前配置中
overrideParameters传递的参数名foo与ARM模板定义的参数名fooBar不匹配,属于配置笔误 - 传递JSON字符串时的引号嵌套会导致ARM解析JSON时识别到非法字符
修正步骤
1. 调整PowerShell输出逻辑
增加JSON转换深度,同时转义JSON内的双引号,避免传递时出现引号冲突:
$keyVault = Get-AzKeyVault -Name $keyVaultName -ResourceGroupName $resourceGroupName $keyVaultAccessPolicies = $keyVault.AccessPolicies # 增加Depth参数避免结构截断,转义双引号避免传递时被提前识别为字符串结束符 $json = $keyVaultAccessPolicies | ConvertTo-Json -Compress -Depth 10 | ForEach-Object { $_ -replace '"', '\"' } Write-Host "##vso[task.setvariable variable=SAUCE;isOutput=true;]$json"
2. 修正ARM模板部署任务配置
修正参数名匹配问题,使用标准ADO变量引用方式:
- task: AzureResourceManagerTemplateDeployment@3 displayName: 'Provision Key Vault' inputs: deploymentScope: 'Resource Group' azureResourceManagerConnection: ${{ parameters.azureSubscriptionName }} subscriptionId: ${{ parameters.azureSubscriptionId }} action: 'Create Or Update Resource Group' resourceGroupName: '$(Resource.Group.Name)' location: '$(Region)' templateLocation: 'Linked artifact' csmFile: '$(Provisioning.Package.Name)/Templates/key-vault-deploy.json' deploymentMode: 'Incremental' overrideParameters: >- -name "$(KeyVault.Name)" -fooBar "$(accesspolicyreference_SAUCE)" -location "$(Region)" -tenant "[subscription().tenantId]"
3. 补全ARM模板缺失的参数定义
你当前模板中引用的location、tenant、tags都没有在参数段定义,需要补全避免部署报错:
{ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "name": { "type": "string" }, "fooBar": { "type": "string" }, "location": { "type": "string" }, "tenant": { "type": "string" }, "tags": { "type": "object", "defaultValue": {} } }, "variables": { }, "resources": [ { "apiVersion": "2018-02-14", "name": "[parameters('name')]", "location": "[parameters('location')]", "type": "Microsoft.KeyVault/vaults", "properties": { "accessPolicies": "[json(parameters('fooBar'))]", "enabledForDeployment": false, "enabledForTemplateDeployment": true, "enabledForDiskEncryption": false, "enableRbacAuthorization": false, "tenantId": "[parameters('tenant')]", "sku": { "name": "Standard", "family": "A" }, "enableSoftDelete": false, "networkAcls": { "defaultAction": "allow", "bypass": "AzureServices", "ipRules": [], "virtualNetworkRules": [] } }, "tags": "[parameters('tags')]", "dependsOn": [] } ], "outputs": {} }
可选简化方案
如果不想做JSON转义,可直接将ARM模板的fooBar参数类型改为array,部署任务的overrideParameters中传递变量时去掉外层引号:-fooBar $(accesspolicyreference_SAUCE),模板中直接使用"accessPolicies": "[parameters('fooBar')]"即可,不需要调用json()函数解析。
内容的提问来源于stack exchange,提问作者Dr Schizo
相关产品推荐
相关产品推荐

