Azure RM模板。将复杂值传递给第3级嵌套模板

时间:2017-02-20 20:49:09

标签: azure

我有一个包含2级嵌套模板的父模板,azuredeploy.json-> vmReferenceTemplate.json-> datadiskreference.json当我将所需的值从第2级传递到第3级时,它部署得很好,但它没有将完全相同的值从第1级传递到第3级嵌套模板时不起作用。我想从azuredeploy.json到datadiskreference.json的numDataDisks值我有一个非常复杂的模板,为了使它工作,我必须从第一级传递值。这是有条纹的版本。 azuredeploy.json:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "parameters": {
    ,,,
    "numberOfVMs": {
      "type": "int",
      "defaultValue": 8,
    },
    "numberOfDataDisks": {
      "type": "array",
      "defaultValue": [
        2,
        1,
        3,
        1,
        1,
        1,
        1,
        1
      ]
    },
    ...
  },
  "resources": [
    {
      "name": "[concat(parameters('vmName'), copyIndex(1),'-','reference')]",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2016-09-01",
      "copy": {
        "name": "vmReferenceTemplateLoop",
        "count": "[parameters('numberOfVMs')]"
      },
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[concat(parameters('_artifactsLocation'), '/', variables('vmReferenceTemplateTemplateFolder'), '/', variables('vmReferenceTemplateTemplateFileName'), parameters('_artifactsLocationSasToken'))]",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "numDataDisks": {
            "value": "[parameters('numberOfVMs')]"
          }
        }
      }
    }
  ],
...

vmReferenceTemplate.json:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "parameters": {
    ...
    "numberOfVMs": {
      "type": "int",
      "defaultValue": 2
    },
    "numberOfDataDisks": {
      "type": "array",
      "defaultValue": [
        2,
        1,
        3,
        1,
        1,
        1,
        1,
        1
      ]
    },
    ...
  },
  "resources": 
    {
      "apiVersion": "2016-09-01",
      "name": "[parameters('dataDisksReferenceTemplateName')]",
      "type": "Microsoft.Resources/deployments",
      "copy": {
        "name": "dataDiskReferenceLoop",
        "count": "[parameters('copyNestedReference')]"
      },
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[variables('dataDiskReferenceTemplateUri')]",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "vmName": {
            "value": "[parameters('dataDisksVMnameReference')]"
          },
          "storageAccountName": {
            "value": "[variables('var_storageAccountName')]"
          },
          "numDataDisks": {
            "value": "[parameters('numberOfDataDisks')[copyIndex()]]"
          },
          "sizeOfEachDataDiskInGB": {
            "value": "[variables('sizeOfEachDataDiskInGB')]"
          }
        }
      }
    }
  ],
  ...

这就是我尝试将值从第1级传递到第3级的方法,但它失败并显示错误"Deployment template validation failed: 'The provided value for the template parameter 'numDataDisks' at line '36' and column '22' is not valid.'." azuredeploy.json

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "parameters": {
    ,,,
    "numberOfVMs": {
      "type": "int",
      "defaultValue": 8,
    },
    "numberOfDataDisks": {
      "type": "array",
      "defaultValue": [
        2,
        1,
        3,
        1,
        1,
        1,
        1,
        1
      ]
    },
    ...
  },
  "resources": [
    {
      "name": "[concat(parameters('vmName'), copyIndex(1),'-','reference')]",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2016-09-01",
      "copy": {
        "name": "vmReferenceTemplateLoop",
        "count": "[parameters('numberOfVMs')]"
      },
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[concat(parameters('_artifactsLocation'), '/', variables('vmReferenceTemplateTemplateFolder'), '/', variables('vmReferenceTemplateTemplateFileName'), parameters('_artifactsLocationSasToken'))]",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "numDataDisks": {
            "value": "[parameters('numberOfDataDisks')[copyIndex()]]"
          }
        }
      }
    }
  ]
...

vmReferenceTemplate.json:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "parameters": {
    ,,,
    "numberOfVMs": {
      "type": "int",
      "defaultValue": 2,
    },
    "numberOfDataDisks": {
      "type": "array",
      "defaultValue": [
        2,
        1,
        3,
        1,
        1,
        1,
        1,
        1
      ]
    },
    ...
  },
  "resources": [
    {
      "apiVersion": "2016-09-01",
      "name": "[parameters('dataDisksReferenceTemplateName')]",
      "type": "Microsoft.Resources/deployments",
      "copy": {
        "name": "dataDiskReferenceLoop",
        "count": "[parameters('copyNestedReference')]"
      },
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[variables('dataDiskReferenceTemplateUri')]",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "vmName": {
            "value": "[parameters('dataDisksVMnameReference')]"
          },
          "storageAccountName": {
            "value": "[variables('var_storageAccountName')]"
          },
          "numDataDisks": {
            "value": "[parameters('numDataDisks')]"
          },
          "sizeOfEachDataDiskInGB": {
            "value": "[variables('sizeOfEachDataDiskInGB')]"
          }
        }
      }
    }
  ]
...

2 个答案:

答案 0 :(得分:3)

在这里,伙计们,就像我在评论中所说的,让我们做一个魔术!让我们创建一个包含2个嵌套模板的模板,但是将1个嵌套模板的输出传递给另一个模板!

"resources": [
    {
        ...
        "dependsOn": [
            "datadiskcopy" << DEPENDS ON ANOTHER TEMPLATE COPY LOOP !!!
        ],
        ...
            "parameters": {
                "adminPassword": {
                    "reference": {
                        "keyVault": {
                            "id": "/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.KeyVault/vaults/xxx"
                        },
                        "secretName": "[concat('secret', copyindex(1))]"
                    } << KEYVAULT REFERENCE YOU NEED !!
                },
                "diskObject": {
                    "value": "[reference(concat('nested-datadisk-', copyIndex())).outputs.result.value]" << REFERENCE ANOTHER NESTED DEPLOYMENT OUTPUT !!
                }
            }
        }
    },
    {
        "apiVersion": "2016-09-01",
        "name": "[concat('nested-datadisk-', copyIndex())]",
        "type": "Microsoft.Resources/deployments",
        "copy": {
            "name": "datadiskcopy",
            "count": "[parameters('LoopCount')]"
        },
        "properties": {
            "mode": "Incremental",
            "templateLink": {
                "uri": "https://raw.githubusercontent.com/4c74356b41/armotron/master/ml-vm-ml-dd-kv-nst-dd",
                "contentVersion": "1.0.0.0"
            },
            "parameters": {
                "numDataDisks": {
                    "value": "[parameters('numberOfDataDisksPerVM')[copyIndex()]]"
                }
            }
        }
    }

我将很快更新链接,因为我决定稍微重命名模板,但您可以在我的github上查看armotron repo已有的样本。

为了简单起见,这是使用托管磁盘,但你可以使用非托管(将成为硬核,你)

PS。您可能会再次遇到缓存问题,而不是从RAW链接复制数据。刚试过这个东西,对我有用,你可以进一步扩展它。

答案 1 :(得分:1)

虽然这并没有直接回答你的问题,但它可能会对更好的解决方案有所了解。我们使用ARM模板进行了几轮配置,以配置我们的Azure基础架构,包括您现在正在执行的嵌套模板。我们最终放弃了嵌套模板,原因如下:

  1. 他们最终在重用方面提供的价值很小。每次我们想要重用共享模板时,它几乎总是需要对所讨论的特定方案进行一些调整。这意味着可以在公共互联网上提供版本号,进行调整并使新版本可用,同时还提供旧版本。
  2. 缺乏条件构造(是的,你可以破解它们,但它使模板不清楚)使得实现可重用模板变得更加困难。
  3. 我们的ARM模板目前是这样的:每个资源组在我们的Github帐户中都有自己的git-repository,资源组中的每个资源都有自己的模板。资源组的存储库查找如下所示的实例:

    my_group
    ├── cloud-config.yaml
    ├── deploy.ps1
    ├── deploy.sh
    └── resources
        ├── load_balancer.json
        ├── nsg.json
        ├── storage_account.json
        └── virtual_machine.json
    

    为每个资源提供单独的模板使维护变得更加容易。 deploy.sh文件目前只是一系列az group deployment create - 部署所有文件的命令,与powershell脚本相同。我们不再需要在没有身份验证的情况下在公共Internet上安装我们的ARM模板。您还会注意到,由于此ARM模板仅用于一个原因组,因此我们不再需要参数文件,参数将与其余代码一起处理。

    我相信这个设置比一个巨型ARM模板提供了更多的灵活性,具体取决于嵌套模板。我们可以孤立地管理我们想要的所有内容(例如cloud-config.yaml),然后使用脚本生成用于部署的ARM模板。我们目前正在尝试为每个部署创建一个git-tag,然后使用git来确定自上次部署以来哪些文件已经更改。