2
votes

It looks like I have hit a limitation of ARM templates and was hoping someone may be able to advise on a work around.

My deployVM.json template uses the copy function to create managed datadisks, which works without issue, however, I need to attach an additonal datadisk that does not follow the copy pattern.

Properties.storageprofile:

  "copy": [
            {
              "name": "dataDisks",
              "count": "[length(parameters('sharedVariables').disks.config)]",
              "input": {
                "name": "[concat(variables('vmName'),'-',parameters('sharedVariables').disks.config[CopyIndex('dataDisks')].name)]",
                "diskSizeGB": "[parameters('sharedVariables').disks.config[CopyIndex('dataDisks')].diskSizeGB]",
                "lun": "[parameters('sharedVariables').disks.config[copyIndex('dataDisks')].lun]",
                "createOption": "Empty",
                "managedDisk": {
                  "storageAccountType": "[parameters('sharedVariables').disks.accountType]"
                }
              }
            }
          ]
  • Creating a second instance of datadisks[] property is not allowed,

  • Creating a second instance of the whole VM resource is also not allowed,

So I created a child template to get around the above limitations. The child template creates the datadisk and attaches it to the vm, but in doing the attach, it unattaches the disks attached in deployVM.json:

"resources" : [
    //Create a managed disk using an existing VHD
    {
      "apiVersion": "2017-03-30",
      "type": "Microsoft.Compute/disks",
      "name": "[concat(parameters('vmName'),'-mediadisk-001')]",
      "location": "[resourceGroup().location]",
      "tags": {
        "Purpose": "Managed disk containing VHD of installation media",
        "createdBy": "[parameters('sharedVariables').createdBy]"
      },
      "sku": {
        "name": "[parameters('sharedVariables').media.storageAccountType]"
      },
      "properties": {
        "creationData": {
          "createOption": "Import",
          "sourceUri": "[parameters('sharedVariables').media.sourceVhdUri]"
        },
        "diskSizeGB": "[parameters('sharedVariables').media.vhdManagedDiskSize]"
      }
    },
    //Attach managed disk to existing VM
    {
      "apiVersion": "2017-03-30",
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[parameters('vmName')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [ "[concat(parameters('vmName'),'-mediadisk-001')]" ],
      "properties": {
        "storageProfile": {
          "dataDisks": [
            {
              "lun": "[add(length(parameters('sharedVariables').disks.config),1)]",
              "name": "[concat(parameters('vmName'),'-mediadisk-001')]",
              "createOption": "Attach",
              "managedDisk": {
                "id": "[resourceId('Microsoft.Compute/disks/', concat(parameters('vmName'),'-mediadisk-001'))]"
              }
            }
          ]
        }
      }
    }
]

Maybe I should try the attach without creating the managed datadisk. Afterall, it is a VHD, so in the child template the above was replaced with just:

"resources" : [
    {
      "apiVersion": "2017-03-30",
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[parameters('vmName')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [],
      "properties": {
        "storageProfile": {
          "dataDisks": [
            {
              "lun": "[add(length(parameters('sharedVariables').disks.config),1)]",
              "name": "[concat(parameters('vmName'),'-mediadisk-001')]",
              "createOption": "FromImage",
              "image": {
                "uri": "concat(parameters('vmName'),'-mediadisk-001')"
              },
              "vhd": {
                "uri": "[parameters('sharedVariables').media.sourceVhdUri]"
              },
              "managedDisk": {
                  "id": "[resourceId('Microsoft.Compute/disks/', concat(parameters('vmName'),'-mediadisk-001'))]"
              }
            }
          ]
        }
      }
    }
]

It then proceeded to complain about "Addition of a blob based disk to VM with managed disks is not supported. Really, so is this saying one cannot use both the managed disks and storage account disk? One last attempt, I removed the lines:

"managedDisk": {
              "id": "[resourceId('Microsoft.Compute/disks/', concat(parameters('vmName'),'-mediadisk-001'))]"
          }

But same error.

I can reattach the disks in the portal and my only other thought, without going back to storage account disks, is to create another copy[] function in the child template to reattach. This sounds crazy, so I'm assuming it's a feature request, or I need schooling!

TIA

Update I've removed datadisks resource from deployVM.json template and added two child templates, one for each "type" of data disk. The copy() and the single VHD, but it is still detaching the copy() disks from the first child, when the second child attaches its disk.

1
you cannot have managed and unmanaged disks on the same vm4c74356b41
Thanks @4c74356b41. So I have to go with the first option of wrapping the VHD in a managed disk. So why does the deployment detach existing disks? It must be supported, as I can add them back in the GUI. Just can't find a) why they're detaching in the first place and b) how to reattach.woter324

1 Answers

2
votes

So its detaching existing disks because its using a declarative approach. Your second deployment defines only 1 data disk, so it gives you what you are asking for. 1 disk on a vm.

You don't really have a lot of options to overcome this. use external tool (like powershell) to create json for you and pass it in directly or use arm templates to create a json object that will contain all the disks and pass it into the resource.

      [
        {
          "lun": "[add(length(parameters('sharedVariables').disks.config),1)]",
          "name": "[concat(parameters('vmName'),'-mediadisk-001')]",
          "createOption": "Attach",
          "managedDisk": {
            "id": "[resourceId('Microsoft.Compute/disks/', concat(parameters('vmName'),'-mediadisk-001'))]"
          }
        },
        {
          "lun": "[add(length(parameters('sharedVariables').disks.config),1)]",
          "name": "[concat(parameters('vmName'),'-mediadisk-001')]",
          "createOption": "Attach",
          "managedDisk": {
            "id": "[resourceId('Microsoft.Compute/disks/', concat(parameters('vmName'),'-mediadisk-001'))]"
          }
        }
      ]

sample powershell object to reflect that:

@(@{lun=xxx;...},@{...})