将数组传递给 ARM 模板 [英] Pass array to ARM Template
问题描述
我正在尝试将数组从 AzurePowerShell 任务传递到 ARM 模板,但我不确定如何执行此操作.
I am trying to pass an array from an AzurePowerShell task to an ARM template but I am not sure how to do this.
我收到错误:
- 当我尝试将其作为字符串传递然后在 ARM 中使用 json 函数时,json 无效,尽管当我打印出 json 并对其进行 lint 时,它是有效的 json.
- 当模板需要一个对象时,无法将字符串转换为对象.
感谢任何帮助.
我有一个 powershell 脚本,可以从我的密钥保管库中获取访问策略:
I have a powershell script that grabs the access policies from my key vault:
$keyVault = Get-AzKeyVault -Name $keyVaultName -ResourceGroupName $resourceGroupName
$keyVaultAccessPolicies = $keyVault.AccessPolicies
$json = $keyVaultAccessPolicies | ConvertTo-Json -Compress
Write-Host "##vso[task.setvariable variable=SAUCE;isOutput=true;]$json"
编辑我可以在调试为数组时看到该值,因为它被方括号包围.然而,当在管道中输出时,方括号被省略了.我觉得这很奇怪,不明白为什么要这样做.
EDIT I can see the value when debugging to be an array as its surrounded by square brackets. However, when outputted in pipelines the square bracket is omitted out. I find this strange and don't understand why its doing that.
但是,我现在如何将其传递给模板?
However, how do I now pass this to a template?
- 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)"
-foo "$env:accesspolicyreference_SAUCE"
这是密钥保管库模板
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string"
},
"fooBar": {
"type": "string"
}
},
"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": "[variables('tags')]",
"dependsOn": []
}
],
"outputs": {}
}
推荐答案
这里有几个问题:
- 如果没有正确转义,使用 json 字符串覆盖 arm 模板参数可能会给您带来麻烦.我建议您将 json 编码为 base64 字符串:
$keyVault = Get-AzKeyVault -Name 'vaultbyenar2htogee'
$keyVaultAccessPolicies = $keyVault.AccessPolicies
$json = $keyVaultAccessPolicies | ConvertTo-Json -Compress
$sauce64 = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($json))
Write-Host "##vso[task.setvariable variable=SAUCE]$sauce64"
有一个arm模板函数base64ToJson() 直接将 base64 编码的 json 字符串解码为对象:
There is an arm template function base64ToJson() that directly decodes base64 encoded json strings into objects:
"variables": {
"fooBar": "[base64ToJson(parameters('fooBar'))]"
}
- 您从
$keyVault.AccessPolicies
获取的对象不是 accessPolicies 属性在 arm 模板中.为了使其工作,您需要使用 复制循环:
- The object that you get from
$keyVault.AccessPolicies
is not a valid value for the accessPolicies property in the arm template. In order to make it work, you need to map the values into the correct structure with a copy-loop:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"fooBar": {
"type": "string"
}
},
"variables": {
"fooBar": "[base64ToJson(parameters('fooBar'))]"
},
"resources": [
{
"apiVersion": "2018-02-14",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"type": "Microsoft.KeyVault/vaults",
"properties": {
"copy": [ {
"name": "accessPolicies",
"count": "[length(variables('fooBar'))]",
"input": {
"tenantId": "[subscription().tenantId]",
"objectId": "[variables('fooBar')[copyIndex('accessPolicies')].ObjectId]",
"permissions": {
"keys": "[variables('fooBar')[copyIndex('accessPolicies')].PermissionsToKeys]",
"secrets": "[variables('fooBar')[copyIndex('accessPolicies')].PermissionsToSecrets]",
"certificates": "[variables('fooBar')[copyIndex('accessPolicies')].PermissionsToCertificates]"
}
}
}],
"enabledForDeployment": false,
"enabledForTemplateDeployment": true,
"enabledForDiskEncryption": false,
"enableRbacAuthorization": false,
"tenantId": "[subscription().tenantid]",
"sku": {
"name": "Standard",
"family": "A"
},
"enableSoftDelete": false,
"networkAcls": {
"defaultAction": "allow",
"bypass": "AzureServices",
"ipRules": [],
"virtualNetworkRules": []
}
},
"dependsOn": []
}
],
"outputs": {}
}
- 如果您将在同一作业的下游任务中使用管道变量,则无需使用
;isOutput=true
.(否则,您需要在变量前面加上设置它的任务的名称,例如:$(myTask.SAUCE)
).
- No need to use
;isOutput=true
if you will use the pipeline variable in a downstream task within the same job. (Otherwise you need to prefix the variable with the name of the task in which it was set, like:$(myTask.SAUCE)
).
这篇关于将数组传递给 ARM 模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!