ARM参数数组中的关键文件库引用

时间:2019-02-04 15:35:52

标签: azure-resource-manager azure-keyvault

我经常在ARM的模板参数文件中使用密钥库引用来安全地传递秘密。

现在,我没有传递奇异的密钥库参数,而是尝试传递一组由密钥库引用的对象。不幸的是,这是行不通的。有关背景信息:我正在尝试从主密钥库部署/派生辅助密钥库,并传输/复制一些条目。

为此,请在我的模板中部署以下资源:

{
            "type": "Microsoft.KeyVault/vaults",
            "name": "my-new-sub-vault",
            "apiVersion": "2015-06-01",
            "location": "[resourceGroup().location]",
            "properties": {
                "enabledForDeployment": "false",
                "enabledForTemplateDeployment": "false",
                "enabledForVolumeEncryption": "false",
                "tenantId": "[subscription().tenantId]",
                "accessPolicies": [
                    {
                        "tenantId": "[subscription().tenantId]",
                        "objectId": "[parameters('msiObjectId')]",
                        "permissions": {
                            "keys": ["get", "list"],
                            "secrets": ["get", "list"]
                        }
                    }
                ],
                "sku": {
                    "name": "Standard",
                    "family": "A"
                }
            }
        },
        {
            "type": "Microsoft.KeyVault/vaults/secrets",
            "name": "[concat('my-new-sub-vault', '/', parameters('secretsObject').secrets[copyIndex()].secretName)]",
            "apiVersion": "2015-06-01",
            "properties": {
                "value": "[parameters('secretsObject').secrets[copyIndex()].secretValue]"
            },
            "dependsOn": [
                "[concat('Microsoft.KeyVault/vaults/my-new-sub-vault')]"
            ],
            "copy": {
                "name": "secretsCopy",
                "count": "[length(parameters('secretsObject').secrets)]"
            }
        }

我的语法是否有错误?还是不可能?

引发的错误是

  

New-AzResourceGroupDeployment:16:25:54-   资源Microsoft.KeyVault /保险库/秘密   “ my-new-sub-vault / my-secret”失败,并显示消息“ {”“错误”:{       “ code”:“ BadRequest”,       “ message”:“秘密不见了”}}'

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "secretsObject": {
            "value": {
                "secrets": [						
                    ...,
                    {
                        "secretName": "my-secret",
                        "secretValue": {
                            "reference": {
                              "keyVault": {
                                "id": "/subscriptions/subId/resourceGroups/main/providers/Microsoft.KeyVault/vaults/master-vault"
                              },
                              "secretName": "my-secret"
                            }
                        }
                    }
                ]
            }
        }
    }
}

欢呼

2 个答案:

答案 0 :(得分:1)

另一种选择是将机密存储到KeyVault中的单个机密中,格式为JSON对象。然后,您可以使用单个资源来编写它,并使用单个引用来读取它。您可以使用string()和json()函数将其与在部署期间可以使用的对象进行转换。

要创建“单个机密”:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "keyVaultName": {
      "type": "string",
      "metadata": {
        "description": "Name of the vault"
      }
    },
    "secretName": {
      "type": "string",
      "metadata": {
        "description": "Name of the secret to store in the vault"
      }
    },
    "secretValue": {
      "type": "secureObject",
      "metadata": {
        "description": "Value of the secret to store in the vault"
      }
    }
  },
  "variables": { },
  "resources": [
    {
      "type": "Microsoft.KeyVault/vaults/secrets",
      "name": "[concat(parameters('keyVaultName'), '/', parameters('secretName'))]",
      "apiVersion": "2018-02-14",
      "tags": {
        "displayName": "secret"
      },
      "properties": {
        "value": "[string(parameters('secretValue'))]"
      }
    }
  ]
}

使用它来消耗机密:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "secretValue": {
      "type": "securestring"
    }
  },
  "variables": {
    "toJSON": "[json(parameters('secretValue'))]"
  },
  "resources": [ ],
  "outputs": {
    "secretValue": {
      "type": "string",
      "value": "[parameters('secretValue')]"
    },
    "singleObj": {
      "type": "object",
      "value": "[variables('toJSON')]"
    },
    "singleProperty": {
      "type": "string",
      "value": "[variables('toJSON').two]"
    }
  }
}

参数文件将在创建密码时包含一个带有您的机密的json对象,然后像在OP中一样使用引用参数语法进行引用。

答案 1 :(得分:0)

不幸的是,

无法正常工作,但是,您可以使用嵌套模板循环来解决此问题。像这样的东西:

{
    "apiVersion": "2017-05-10",
    "name": "[concat('kvReference-', copyIndex())]",
    "type": "Microsoft.Resources/deployments",
    "copy": {
        "name": "kvReference",
        "count": 2
    },
    "properties": {
        "mode": "Incremental",
        "templateLink": {
            "uri": "[uri(deployment().properties.templateLink.uri, 'nested-kv-reference.json')]"
        },
        "parameters": {
            "parameter": {
                "reference": {
                    "keyVault": {
                        "id": "[variables('kvUri')]"
                    },
                    "secretName": "secretName"
                }
            }
        }
    }
},

,嵌套模板必须按原样输出它们,然后可以在模板中稍后引用它们:

reference('kvReference-', copyIndex()).outputs.valueName.value

,或者您可以将它们用作嵌套模板中的参数。您可以将它们设置为安全的字符串类型,以使这些值不会在portal \ api中公开。