【问题标题】:Pass array to ARM Template将数组传递给 ARM 模板
【发布时间】:2021-06-16 06:48:41
【问题描述】:

我正在尝试将数组从 AzurePowerShell 任务传递到 ARM 模板,但我不确定如何执行此操作。

我得到错误:

  • 当我尝试将其作为字符串传递然后在 ARM 中使用 json 函数时,json 无效,尽管当我将 json 打印出来并对其进行 lint 处理时,它是有效的 json。
  • 当模板需要一个对象时,无法将字符串转换为对象。

感谢任何帮助。

我有一个 powershell 脚本,可以从我的密钥保管库中获取访问策略:

$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"

编辑 我可以在调试为数组时看到值,因为它被方括号括起来。但是,当在管道中输出时,方括号会被省略。我觉得这很奇怪,不明白为什么要这样做。

但是,我现在如何将其传递给模板?

  - 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": {}
}

【问题讨论】:

    标签: azure-devops azure-pipelines arm-template


    【解决方案1】:

    这里有几个问题:

    1. 如果未正确转义,使用 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字符串解码成对象:

     "variables": {
          "fooBar": "[base64ToJson(parameters('fooBar'))]"
      }
    
    1. 您从$keyVault.AccessPolicies 获得的对象不是arm 模板中accessPolicies 属性的有效值。为了使其正常工作,您需要使用 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": {}
    }
    
    
    1. 如果您将在同一作业的下游任务中使用管道变量,则无需使用;isOutput=true。 (否则,您需要在变量前面加上设置它的任务名称,例如:$(myTask.SAUCE))。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-29
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      • 2018-08-29
      • 2019-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多