Máquinas virtuais num modelo do Azure Resource Manager

Aplica-se a: ✔️ VMs do Windows

Este artigo descreve aspetos de um modelo do Azure Resource Manager que se aplicam a máquinas virtuais. Este artigo não descreve um modelo completo para criar uma máquina virtual; para que precise de definições de recursos para contas de armazenamento, interfaces de rede, endereços IP públicos e redes virtuais. Para obter mais informações sobre como estes recursos podem ser definidos em conjunto, veja as instruções Resource Manager modelo.

Existem muitos modelos na galeria que incluem o recurso da VM. Nem todos os elementos que podem ser incluídos num modelo são descritos aqui.

Este exemplo mostra uma secção de recursos típica de um modelo para criar um número especificado de VMs:

"resources": [
  {
    "apiVersion": "2016-04-30-preview",
    "type": "Microsoft.Compute/virtualMachines",
    "name": "[concat('myVM', copyindex())]",
    "location": "[resourceGroup().location]",
    "copy": {
      "name": "virtualMachineLoop",
      "count": "[parameters('numberOfInstances')]"
    },
    "dependsOn": [
      "[concat('Microsoft.Network/networkInterfaces/myNIC', copyindex())]"
    ],
    "properties": {
      "hardwareProfile": {
        "vmSize": "Standard_DS1"
      },
      "osProfile": {
        "computername": "[concat('myVM', copyindex())]",
        "adminUsername": "[parameters('adminUsername')]",
        "adminPassword": "[parameters('adminPassword')]"
      },
      "storageProfile": {
        "imageReference": {
          "publisher": "MicrosoftWindowsServer",
          "offer": "WindowsServer",
          "sku": "2012-R2-Datacenter",
          "version": "latest"
        },
        "osDisk": {
          "name": "[concat('myOSDisk', copyindex())]",
          "caching": "ReadWrite",
          "createOption": "FromImage"
        },
        "dataDisks": [
          {
            "name": "[concat('myDataDisk', copyindex())]",
            "diskSizeGB": "100",
            "lun": 0,
            "createOption": "Empty"
          }
        ]
      },
      "networkProfile": {
        "networkInterfaces": [
          {
            "id": "[resourceId('Microsoft.Network/networkInterfaces',
              concat('myNIC', copyindex()))]"
          }
        ]
      },
      "diagnosticsProfile": {
        "bootDiagnostics": {
          "enabled": "true",
          "storageUri": "[concat('https://', variables('storageName'), '.blob.core.windows.net')]"
        }
      }
    },
    "resources": [
      {
        "name": "Microsoft.Insights.VMDiagnosticsSettings",
        "type": "extensions",
        "location": "[resourceGroup().location]",
        "apiVersion": "2016-03-30",
        "dependsOn": [
          "[concat('Microsoft.Compute/virtualMachines/myVM', copyindex())]"
        ],
        "properties": {
          "publisher": "Microsoft.Azure.Diagnostics",
          "type": "IaaSDiagnostics",
          "typeHandlerVersion": "1.5",
          "autoUpgradeMinorVersion": true,
          "settings": {
            "xmlCfg": "[base64(concat(variables('wadcfgxstart'),
            variables('wadmetricsresourceid'),
            concat('myVM', copyindex()),
            variables('wadcfgxend')))]",
            "storageAccount": "[variables('storageName')]"
          },
          "protectedSettings": {
            "storageAccountName": "[variables('storageName')]",
            "storageAccountKey": "[listkeys(variables('accountid'),
              '2015-06-15').key1]",
            "storageAccountEndPoint": "https://core.windows.net"
          }
        }
      },
      {
        "name": "MyCustomScriptExtension",
        "type": "extensions",
        "apiVersion": "2016-03-30",
        "location": "[resourceGroup().location]",
        "dependsOn": [
          "[concat('Microsoft.Compute/virtualMachines/myVM', copyindex())]"
        ],
        "properties": {
          "publisher": "Microsoft.Compute",
          "type": "CustomScriptExtension",
          "typeHandlerVersion": "1.7",
          "autoUpgradeMinorVersion": true,
          "settings": {
            "fileUris": [
              "[concat('https://', variables('storageName'),
                '.blob.core.windows.net/customscripts/start.ps1')]"
            ],
            "commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File start.ps1"
          }
        }
      }
    ]
  }
]

Nota

Este exemplo baseia-se numa conta de armazenamento criada anteriormente. Pode criar a conta de armazenamento ao implementá-la a partir do modelo. O exemplo também se baseia numa interface de rede e nos respetivos recursos dependentes que seriam definidos no modelo. Estes recursos não são apresentados no exemplo.

Versão da API

Quando implementa recursos com um modelo, tem de especificar uma versão da API a utilizar. O exemplo mostra o recurso da máquina virtual com este elemento apiVersion:

"apiVersion": "2016-04-30-preview",

A versão da API que especificar no modelo afeta as propriedades que pode definir no modelo. Em geral, deve selecionar a versão mais recente da API ao criar modelos. Para modelos existentes, pode decidir se pretende continuar a utilizar uma versão anterior da API ou atualizar o modelo para a versão mais recente para tirar partido das novas funcionalidades.

Utilize estas oportunidades para obter as versões mais recentes da API:

Parâmetros e variáveis

Os parâmetros facilitam a especificação de valores para o modelo ao executá-lo. Esta secção de parâmetros é utilizada no exemplo:

"parameters": {
  "adminUsername": { "type": "string" },
  "adminPassword": { "type": "securestring" },
  "numberOfInstances": { "type": "int" }
},

Quando implementa o modelo de exemplo, introduz valores para o nome e palavra-passe da conta de administrador em cada VM e o número de VMs a criar. Tem a opção de especificar valores de parâmetros num ficheiro separado que é gerido com o modelo ou fornecer valores quando lhe for pedido.

As variáveis facilitam a configuração de valores no modelo que são utilizados repetidamente ao longo do mesmo ou que podem ser alterados ao longo do tempo. Esta secção de variáveis é utilizada no exemplo:

"variables": {
  "storageName": "mystore1",
  "accountid": "[concat('/subscriptions/', subscription().subscriptionId,
    '/resourceGroups/', resourceGroup().name,
  '/providers/','Microsoft.Storage/storageAccounts/', variables('storageName'))]",
  "wadlogs": "<WadCfg>
    <DiagnosticMonitorConfiguration overallQuotaInMB=\"4096\" xmlns=\"http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration\">
      <DiagnosticInfrastructureLogs scheduledTransferLogLevelFilter=\"Error\"/>
      <WindowsEventLog scheduledTransferPeriod=\"PT1M\" >
        <DataSource name=\"Application!*[System[(Level = 1 or Level = 2)]]\" />
        <DataSource name=\"Security!*[System[(Level = 1 or Level = 2)]]\" />
        <DataSource name=\"System!*[System[(Level = 1 or Level = 2)]]\" />
      </WindowsEventLog>",
  "wadperfcounters": "<PerformanceCounters scheduledTransferPeriod=\"PT1M\">
      <PerformanceCounterConfiguration counterSpecifier=\"\\Process(_Total)\\Thread Count\" sampleRate=\"PT15S\" unit=\"Count\">
        <annotation displayName=\"Threads\" locale=\"en-us\"/>
      </PerformanceCounterConfiguration>
    </PerformanceCounters>",
  "wadcfgxstart": "[concat(variables('wadlogs'), variables('wadperfcounters'),
    '<Metrics resourceId=\"')]",
  "wadmetricsresourceid": "[concat('/subscriptions/', subscription().subscriptionId,
    '/resourceGroups/', resourceGroup().name ,
    '/providers/', 'Microsoft.Compute/virtualMachines/')]",
  "wadcfgxend": "\"><MetricAggregation scheduledTransferPeriod=\"PT1H\"/>
    <MetricAggregation scheduledTransferPeriod=\"PT1M\"/>
    </Metrics></DiagnosticMonitorConfiguration>
    </WadCfg>"
},

Quando implementa o modelo de exemplo, são utilizados valores variáveis para o nome e identificador da conta de armazenamento criada anteriormente. As variáveis também são utilizadas para fornecer as definições para a extensão de diagnóstico. Utilize as melhores práticas para criar modelos do Azure Resource Manager para o ajudar a decidir como pretende estruturar os parâmetros e variáveis no seu modelo.

Ciclos de recursos

Quando precisar de mais do que uma máquina virtual para a sua aplicação, pode utilizar um elemento de cópia num modelo. Este elemento opcional percorre a criação do número de VMs que especificou como parâmetro:

"copy": {
  "name": "virtualMachineLoop",
  "count": "[parameters('numberOfInstances')]"
},

Além disso, observe no exemplo que o índice de ciclo é utilizado ao especificar alguns dos valores do recurso. Por exemplo, se introduziu uma contagem de instâncias de três, os nomes dos discos do sistema operativo são myOSDisk1, myOSDisk2 e myOSDisk3:

"osDisk": {
  "name": "[concat('myOSDisk', copyindex())]",
  "caching": "ReadWrite",
  "createOption": "FromImage"
}

Nota

Este exemplo utiliza discos geridos para as máquinas virtuais.

Tenha em atenção que criar um ciclo para um recurso no modelo pode exigir que utilize o ciclo ao criar ou aceder a outros recursos. Por exemplo, várias VMs não podem utilizar a mesma interface de rede, por isso, se o modelo for executado através da criação de três VMs, também tem de repetir a criação de três interfaces de rede. Ao atribuir uma interface de rede a uma VM, o índice de ciclo é utilizado para identificá-la:

"networkInterfaces": [ {
  "id": "[resourceId('Microsoft.Network/networkInterfaces',
    concat('myNIC', copyindex()))]"
} ]

Dependências

A maioria dos recursos depende de outros recursos para funcionar corretamente. As máquinas virtuais têm de estar associadas a uma rede virtual e, para isso, precisam de uma interface de rede. O elemento dependsOn é utilizado para garantir que a interface de rede está pronta para ser utilizada antes de as VMs serem criadas:

"dependsOn": [
  "[concat('Microsoft.Network/networkInterfaces/', 'myNIC', copyindex())]"
],

Resource Manager implementa em paralelo quaisquer recursos que não estejam dependentes de outro recurso a ser implementado. Tenha cuidado ao definir dependências porque pode, inadvertidamente, abrandar a implementação ao especificar dependências desnecessárias. As dependências podem ser ligadas através de vários recursos. Por exemplo, a interface de rede depende do endereço IP público e dos recursos de rede virtual.

Como sabe se é necessária uma dependência? Observe os valores que definiu no modelo. Se um elemento na definição de recurso da máquina virtual apontar para outro recurso implementado no mesmo modelo, precisa de uma dependência. Por exemplo, a máquina virtual de exemplo define um perfil de rede:

"networkProfile": {
  "networkInterfaces": [ {
    "id": "[resourceId('Microsoft.Network/networkInterfaces',
      concat('myNIC', copyindex())]"
  } ]
},

Para definir esta propriedade, a interface de rede tem de existir. Por conseguinte, precisa de uma dependência. Também tem de definir uma dependência quando um recurso (um subordinado) é definido dentro de outro recurso (um principal). Por exemplo, as definições de diagnóstico e as extensões de script personalizadas são definidas como recursos subordinados da máquina virtual. Não podem ser criadas até que a máquina virtual exista. Por conseguinte, ambos os recursos são marcados como dependentes da máquina virtual.

Perfis

São utilizados vários elementos de perfil ao definir um recurso de máquina virtual. Algumas são necessárias e outras opcionais. Por exemplo, os elementos hardwareProfile, osProfile, storageProfile e networkProfile são necessários, mas o diagnosticsProfile é opcional. Estes perfis definem definições como:

Discos e imagens

No Azure, os ficheiros vhd podem representar discos ou imagens. Quando o sistema operativo num ficheiro vhd é especializado para ser uma VM específica, é referido como um disco. Quando o sistema operativo num ficheiro vhd é generalizado para ser utilizado para criar muitas VMs, é referido como uma imagem.

Criar novas máquinas virtuais e novos discos a partir de uma imagem de plataforma

Quando cria uma VM, tem de decidir que sistema operativo deve utilizar. O elemento imageReference é utilizado para definir o sistema operativo de uma nova VM. O exemplo mostra uma definição para um sistema operativo Windows Server:

"imageReference": {
  "publisher": "MicrosoftWindowsServer",
  "offer": "WindowsServer",
  "sku": "2012-R2-Datacenter",
  "version": "latest"
},

Se quiser criar um sistema operativo Linux, poderá utilizar esta definição:

"imageReference": {
  "publisher": "Canonical",
  "offer": "UbuntuServer",
  "sku": "20.04.2-LTS",
  "version": "latest"
},

Nota

Modifique publisheros valores , offersku e version em conformidade.

As definições de configuração do disco do sistema operativo são atribuídas com o elemento osDisk. O exemplo define um novo disco gerido com o modo de colocação em cache definido como ReadWrite e que o disco está a ser criado a partir de uma imagem de plataforma:

"osDisk": {
  "name": "[concat('myOSDisk', copyindex())]",
  "caching": "ReadWrite",
  "createOption": "FromImage"
},

Criar novas máquinas virtuais a partir de discos geridos existentes

Se quiser criar máquinas virtuais a partir de discos existentes, remova os elementos imageReference e os osProfile e defina estas definições de disco:

"osDisk": {
  "osType": "Windows",
  "managedDisk": {
    "id": "[resourceId('Microsoft.Compute/disks', [concat('myOSDisk', copyindex())])]"
  },
  "caching": "ReadWrite",
  "createOption": "Attach"
},

Criar novas máquinas virtuais a partir de uma imagem gerida

Se quiser criar uma máquina virtual a partir de uma imagem gerida, altere o elemento imageReference e defina estas definições de disco:

"storageProfile": {
  "imageReference": {
    "id": "[resourceId('Microsoft.Compute/images', 'myImage')]"
  },
  "osDisk": {
    "name": "[concat('myOSDisk', copyindex())]",
    "osType": "Windows",
    "caching": "ReadWrite",
    "createOption": "FromImage"
  }
},

Anexar discos de dados

Opcionalmente, pode adicionar discos de dados às VMs. O número de discos depende do tamanho do disco do sistema operativo que utilizar. Com o tamanho das VMs definido como Standard_DS1_v2, o número máximo de discos de dados que podem ser adicionados às mesmas é dois. No exemplo, está a ser adicionado um disco de dados gerido a cada VM:

"dataDisks": [
  {
    "name": "[concat('myDataDisk', copyindex())]",
    "diskSizeGB": "100",
    "lun": 0,
    "caching": "ReadWrite",
    "createOption": "Empty"
  }
],

Extensões

Embora as extensões sejam um recurso separado, estão intimamente associadas às VMs. As extensões podem ser adicionadas como um recurso subordinado da VM ou como um recurso separado. O exemplo mostra a Extensão de Diagnóstico a ser adicionada às VMs:

{
  "name": "Microsoft.Insights.VMDiagnosticsSettings",
  "type": "extensions",
  "location": "[resourceGroup().location]",
  "apiVersion": "2016-03-30",
  "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/myVM', copyindex())]"
  ],
  "properties": {
    "publisher": "Microsoft.Azure.Diagnostics",
    "type": "IaaSDiagnostics",
    "typeHandlerVersion": "1.5",
    "autoUpgradeMinorVersion": true,
    "settings": {
      "xmlCfg": "[base64(concat(variables('wadcfgxstart'),
      variables('wadmetricsresourceid'),
      concat('myVM', copyindex()),
      variables('wadcfgxend')))]",
      "storageAccount": "[variables('storageName')]"
    },
    "protectedSettings": {
      "storageAccountName": "[variables('storageName')]",
      "storageAccountKey": "[listkeys(variables('accountid'),
        '2015-06-15').key1]",
      "storageAccountEndPoint": "https://core.windows.net"
    }
  }
},

Este recurso de extensão utiliza a variável storageName e as variáveis de diagnóstico para fornecer valores. Se quiser alterar os dados recolhidos por esta extensão, pode adicionar mais contadores de desempenho à variável wadperfcounters. Também pode optar por colocar os dados de diagnóstico numa conta de armazenamento diferente do local onde os discos da VM estão armazenados.

Existem muitas extensões que pode instalar numa VM, mas a mais útil é provavelmente a Extensão de Script Personalizado. No exemplo, um script do PowerShell com o nome start.ps1 é executado em cada VM quando é iniciado pela primeira vez:

{
  "name": "MyCustomScriptExtension",
  "type": "extensions",
  "apiVersion": "2016-03-30",
  "location": "[resourceGroup().location]",
  "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/myVM', copyindex())]"
  ],
  "properties": {
    "publisher": "Microsoft.Compute",
    "type": "CustomScriptExtension",
    "typeHandlerVersion": "1.7",
    "autoUpgradeMinorVersion": true,
    "settings": {
      "fileUris": [
        "[concat('https://', variables('storageName'),
          '.blob.core.windows.net/customscripts/start.ps1')]"
      ],
      "commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File start.ps1"
    }
  }
}

O script start.ps1 pode realizar muitas tarefas de configuração. Por exemplo, os discos de dados que são adicionados às VMs no exemplo não são inicializados; pode utilizar um script personalizado para inicializá-los. Se tiver várias tarefas de arranque, pode utilizar o ficheiro start.ps1 para chamar outros scripts do PowerShell no armazenamento do Azure. O exemplo utiliza o PowerShell, mas pode utilizar qualquer método de script que esteja disponível no sistema operativo que estiver a utilizar.

Pode ver o estado das extensões instaladas a partir das definições de Extensões no portal:

Obter o estado da extensão

Também pode obter informações sobre a extensão com o comando Get-AzVMExtension do PowerShell, a extensão vm obter o comando da CLI do Azure ou a API REST Obter informações sobre a extensão .

Implementações

Quando implementa um modelo, o Azure monitoriza os recursos que implementou como um grupo e atribui automaticamente um nome a este grupo implementado. O nome da implementação é o mesmo que o nome do modelo.

Se tiver curiosidade sobre o estado dos recursos na implementação, veja o grupo de recursos no portal do Azure:

Obter informações de implementação

Não é um problema utilizar o mesmo modelo para criar recursos ou atualizar recursos existentes. Quando utiliza comandos para implementar modelos, tem a oportunidade de dizer que modo pretende utilizar. O modo pode ser definido como Completo ou Incremental. A predefinição é fazer atualizações incrementais. Tenha cuidado ao utilizar o modo Concluir porque pode eliminar acidentalmente recursos. Quando definir o modo como Concluído, Resource Manager elimina quaisquer recursos no grupo de recursos que não estejam no modelo.

Passos Seguintes