2
votes

I would like to be able to create VMs amount of which I specify via parameters (achieved by copy) with different secret for each VM (ex. secret1 for VM1, secret2 for VM2, etc.) Here is a basic example of copy VM template:

    {
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "numberOfVMs": {
      "type": "int",
      "defaultValue":  1,
      "minvalue": 1
    },
    "vmAdminUserName": {
      "type": "string",
      "minLength": 1
    },
      "vmAdminPassword": {
          "type": "securestring"
      }
  },
  "variables": {
    "storageAccountName": "[concat('stor567', uniqueString(resourceGroup().id))]",
    "storageAccountType": "Standard_LRS",
    "vmWindowsOSVersion": "2016-Datacenter",
    "vnetPrefix": "10.0.0.0/16",
    "vnetSubnet1Name": "Subnet-1",
    "vnetSubnet1Prefix": "10.0.0.0/24",
    "nicVnetID": "[resourceId('Microsoft.Network/virtualNetworks', 'vnet')]",
    "nicSubnetRef": "[concat(variables('nicVnetID'), '/subnets/', variables('vnetSubnet1Name'))]",
    "vmImagePublisher": "MicrosoftWindowsServer",
    "vmImageOffer": "WindowsServer",
    "vmVmSize": "Standard_DS1_v2",
    "vmVnetID": "[resourceId('Microsoft.Network/virtualNetworks', 'vnet')]",
    "vmSubnetRef": "[concat(variables('vmVnetID'), '/subnets/', variables('vnetSubnet1Name'))]",
    "vmStorageAccountContainerName": "vhds"
  },
  "resources": [
      {
          "name": "[variables('storageAccountName')]",
          "type": "Microsoft.Storage/storageAccounts",
          "location": "[resourceGroup().location]",
          "apiVersion": "2015-06-15",
          "dependsOn": [ ],
        "properties": {
          "accountType": "[variables('storageAccountType')]"
        }
      },
      {
          "name": "vnet",
          "type": "Microsoft.Network/virtualNetworks",
          "location": "[resourceGroup().location]",
          "apiVersion": "2016-03-30",
          "dependsOn": [ ],
          "tags": {
              "displayName": "vnet"
          },
          "properties": {
              "addressSpace": {
                  "addressPrefixes": [
                      "[variables('vnetPrefix')]"
                  ]
              },
              "subnets": [
                  {
                      "name": "[variables('vnetSubnet1Name')]",
                      "properties": {
                          "addressPrefix": "[variables('vnetSubnet1Prefix')]"
                      }
                  }
              ]
          }
      },
    {
      "name": "[concat('NIC',copyindex())]",
      "type": "Microsoft.Network/networkInterfaces",
      "location": "[resourceGroup().location]",
      "copy": {
        "name": "nicLoop",
        "count": "[parameters('numberOfVMs')]"
      },
      "apiVersion": "2016-03-30",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', 'vnet')]"
      ],
      "tags": {
        "displayName": "nic"
      },
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[variables('nicSubnetRef')]"
              }
            }
          }
        ]
      }
    },
    {
      "name": "[concat('VM',copyindex())]",
      "type": "Microsoft.Compute/virtualMachines",
      "location": "[resourceGroup().location]",
      "copy": {
        "name": "virtualMachineLoop",
        "count": "[parameters('numberOfVMs')]"
      },
      "apiVersion": "2015-06-15",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
        "nicLoop"
      ],
      "tags": {
        "displayName": "vm"
      },
      "properties": {
        "hardwareProfile": {
          "vmSize": "[variables('vmVmSize')]"
        },
        "osProfile": {
          "computerName": "[concat('VM',copyindex())]",
          "adminUsername": "[parameters('vmAdminUsername')]",
          "adminPassword": "[parameters('vmAdminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "[variables('vmImagePublisher')]",
            "offer": "[variables('vmImageOffer')]",
            "sku": "[variables('vmWindowsOSVersion')]",
            "version": "latest"
          },
          "osDisk": {
            "name": "vmOSDisk",
            "vhd": {
              "uri": "[concat(reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2016-01-01').primaryEndpoints.blob, variables('vmStorageAccountContainerName'), '/', 'VM',copyIndex(),'-','OSdisk.vhd')]"
            },
            "caching": "ReadWrite",
            "createOption": "FromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', concat('NIC',copyindex()))]"
            }
          ]
        }
      }
    }],
  "outputs": {}
}

However, I'm struggling to integrate using of password as unique secrets from Key Vault in that template. If I use example from official documentation Reference a secret with static id VMs with secret1 for each VM will be created. And I can’t wrap Reference a secret with dynamic id into nested template because that would deploy my copied VMs again and again for the each number of VMs I would like to deploy. Please help me understand, how this challenge can be solved?

1
why cant you do that with a nested template and copyloop? i struggle to understand - 4c74356b41
Because it just wouldn't deploy. pastebin.com/w2p8n0te Suppose I want to create 2 VMs (for example), but that nested is defined as copy in the main template, so ARM tries to deploy that 2 VMs then immediately deploy them again, but with another secret. Here is the main template azuredeploy.json: pastebin.com/tSyPp8fH Here is the nested template nestedTemplate.json: pastebin.com/FTrbmrnc - Max
I think I finally got what you are saying and this case looks interesting. I'll try to create a solution - 4c74356b41

1 Answers

3
votes

Links: Parent and Nested. I'm not sure if that's what you meant (because i still think that i struggle to understand your problem).

These templates allow to deploy variable amount of vm's and use different keyvault keys as passwords for those. Example:

2 Windows VM's with one secret and 3 Ubuntu VM's with another
1 Windows VM with one secret and 4 Ubuntu VM's with another

You can easily extend that to other images, like centos.
As you can probably see after looking at the templates I'm using arrays and copyindex() to feed proper values where they belong.

Tell me if that's not what you are after. Be careful when using those, github raw links use some form of caching, so deploying from github might not work for you with errors, in that case just use the links I've provided (NOT RAW) to copy to local machine and upload to some service like pastebin, and deploy from there.