Aprovisionamento de extensões de sequência no Conjuntos de Dimensionamento de Máquinas Virtuais

As extensões de máquinas virtuais do Azure fornecem capacidades como a gestão e configuração pós-implementação, monitorização, segurança e muito mais. Normalmente, as implementações de produção utilizam uma combinação de várias extensões configuradas para as instâncias de VM alcançarem os resultados pretendidos.

Ao utilizar várias extensões numa máquina virtual, é importante garantir que as extensões que requerem os mesmos recursos do SO não estão a tentar adquirir estes recursos ao mesmo tempo. Algumas extensões também dependem de outras extensões para fornecer configurações necessárias, como definições de ambiente e segredos. Sem a ordenação e sequenciação corretas, as implementações de extensões dependentes podem falhar.

Este artigo detalha como pode sequenciar extensões para serem configuradas para as instâncias de VM no Conjuntos de Dimensionamento de Máquinas Virtuais.

Pré-requisitos

Este artigo pressupõe que está familiarizado com:

Quando utilizar a sequenciação de extensões

Sequencing extensions in not mandatory for scale sets, and unless specified, extensions can be provisioned on a scale set instance in any order.

Por exemplo, se o modelo do conjunto de dimensionamento tiver duas extensões – ExtensionA e ExtensionB – especificadas no modelo, poderá ocorrer uma das seguintes sequências de aprovisionamento:

  • ExtensionA -> ExtensionB
  • ExtensionB -> ExtensionA

Se a sua aplicação exigir que a Extensão A seja sempre aprovisionada antes da Extensão B, deve utilizar a sequenciação de extensões, conforme descrito neste artigo. Com a sequenciação de extensões, só ocorrerá uma sequência:

  • ExtensionA - > ExtensionB

Todas as extensões não especificadas numa sequência de aprovisionamento definida podem ser aprovisionadas em qualquer altura, incluindo antes, depois ou durante uma sequência definida. A sequenciação de extensões especifica apenas que uma extensão específica será aprovisionada após outra extensão específica. Não afeta o aprovisionamento de qualquer outra extensão definida no modelo.

Por exemplo, se o modelo do conjunto de dimensionamento tiver três extensões – Extensão A, Extensão B e Extensão C – especificadas no modelo e a Extensão C estiver definida para ser aprovisionada após a Extensão A, poderá ocorrer uma das seguintes sequências de aprovisionamento:

  • ExtensionA -> ExtensionC -> ExtensionB
  • ExtensionB -> ExtensionA -> ExtensionC
  • ExtensionA -> ExtensionB -> ExtensionC

Se precisar de garantir que nenhuma outra extensão é aprovisionada enquanto a sequência de extensões definida estiver em execução, recomendamos que sequencia todas as extensões no seu modelo de conjunto de dimensionamento. No exemplo acima, a Extensão B pode ser definida para ser aprovisionada após a Extensão C de modo a que só possa ocorrer uma sequência:

  • ExtensionA -> ExtensionC -> ExtensionB

Como utilizar a sequenciação de extensões

Para sequenciar o aprovisionamento de extensões, tem de atualizar a definição da extensão no modelo do conjunto de dimensionamento para incluir a propriedade "provisionAfterExtensions", que aceita uma matriz de nomes de extensões. As extensões mencionadas no valor da matriz de propriedades têm de estar totalmente definidas no modelo do conjunto de dimensionamento.

Implementação de Modelos

O exemplo seguinte define um modelo em que o conjunto de dimensionamento tem três extensões – ExtensionA, ExtensionB e ExtensionC – de modo a que as extensões sejam aprovisionadas pela ordem:

  • ExtensionA -> ExtensionB -> ExtensionC
"virtualMachineProfile": {
  "extensionProfile": {
    "extensions": [
      {
        "name": "ExtensionA",
        "properties": {
          "publisher": "ExtensionA.Publisher",
          "settings": {},
          "typeHandlerVersion": "1.0",
          "autoUpgradeMinorVersion": true,
          "type": "ExtensionA"
        }
      },
      {
        "name": "ExtensionB",
        "properties": {
          "provisionAfterExtensions": [
            "ExtensionA"
          ],
          "publisher": "ExtensionB.Publisher",
          "settings": {},
          "typeHandlerVersion": "2.0",
          "autoUpgradeMinorVersion": true,
          "type": "ExtensionB"
        }
      }, 
      {
        "name": "ExtensionC",
        "properties": {
          "provisionAfterExtensions": [
            "ExtensionB"
          ],
          "publisher": "ExtensionC.Publisher",
          "settings": {},
          "typeHandlerVersion": "3.0",
          "autoUpgradeMinorVersion": true,
          "type": "ExtensionC"                   
        }
      }
    ]
  }
}

Uma vez que a propriedade "provisionAfterExtensions" aceita uma matriz de nomes de extensões, o exemplo acima pode ser modificado de modo a que ExtensionC seja aprovisionado após ExtensionA e ExtensionB, mas não é necessária qualquer ordenação entre ExtensionA e ExtensionB. O modelo seguinte pode ser utilizado para alcançar este cenário:

"virtualMachineProfile": {
  "extensionProfile": {
    "extensions": [
      {
        "name": "ExtensionA",
        "properties": {
          "publisher": "ExtensionA.Publisher",
          "settings": {},
          "typeHandlerVersion": "1.0",
          "autoUpgradeMinorVersion": true,
          "type": "ExtensionA"
        }
      },
      {
        "name": "ExtensionB",
        "properties": {
          "publisher": "ExtensionB.Publisher",
          "settings": {},
          "typeHandlerVersion": "2.0",
          "autoUpgradeMinorVersion": true,
          "type": "ExtensionB"
        }
      }, 
      {
        "name": "ExtensionC",
        "properties": {
          "provisionAfterExtensions": [
            "ExtensionA","ExtensionB"
          ],
          "publisher": "ExtensionC.Publisher",
          "settings": {},
          "typeHandlerVersion": "3.0",
          "autoUpgradeMinorVersion": true,
          "type": "ExtensionC"                   
        }
      }
    ]
  }
}

API REST

O exemplo seguinte adiciona uma nova extensão denominada ExtensionC a um modelo de conjunto de dimensionamento. O ExtensionC tem dependências em ExtensionA e ExtensionB, que já foram definidas no modelo do conjunto de dimensionamento.

PUT on `/subscriptions/subscription_id/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet/extensions/ExtensionC?api-version=2018-10-01`
{ 
  "name": "ExtensionC",
  "properties": {
    "provisionAfterExtensions": [
      "ExtensionA","ExtensionB"
    ],
    "publisher": "ExtensionC.Publisher",
    "settings": {},
    "typeHandlerVersion": "3.0",
    "autoUpgradeMinorVersion": true,
    "type": "ExtensionC" 
  }                  
}

Se o ExtensionC tiver sido definido anteriormente no modelo do conjunto de dimensionamento e quiser agora adicionar as respetivas dependências, pode executar um PATCH para editar as propriedades da extensão já implementada.

PATCH on `/subscriptions/subscription_id/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet/extensions/ExtensionC?api-version=2018-10-01`
{ 
  "properties": {
    "provisionAfterExtensions": [
      "ExtensionA","ExtensionB"
    ]
  }                  
}

As alterações às instâncias existentes do conjunto de dimensionamento são aplicadas na próxima atualização.

Azure PowerShell

Utilize o cmdlet Add-AzVmssExtension para adicionar a extensão Application Health à definição do modelo do conjunto de dimensionamento. A sequenciação de extensões requer a utilização do Az PowerShell 1.2.0 ou superior.

O exemplo seguinte adiciona a extensão Application Health ao extensionProfile num modelo de conjunto de dimensionamento de um conjunto de dimensionamento baseado no Windows. A extensão do Application Health será aprovisionada após o aprovisionamento da Extensão de Script Personalizado, já definida no conjunto de dimensionamento.

# Define the scale set variables
$vmScaleSetName = "myVMScaleSet"
$vmScaleSetResourceGroup = "myVMScaleSetResourceGroup"

# Define the Application Health extension properties
$publicConfig = @{"protocol" = "http"; "port" = 80; "requestPath" = "/healthEndpoint"};
$extensionName = "myHealthExtension"
$extensionType = "ApplicationHealthWindows"
$publisher = "Microsoft.ManagedServices"

# Get the scale set object
$vmScaleSet = Get-AzVmss `
  -ResourceGroupName $vmScaleSetResourceGroup `
  -VMScaleSetName $vmScaleSetName

# Add the Application Health extension to the scale set model
Add-AzVmssExtension -VirtualMachineScaleSet $vmScaleSet `
  -Name $extensionName `
  -Publisher $publisher `
  -Setting $publicConfig `
  -Type $extensionType `
  -TypeHandlerVersion "1.0" `
  -ProvisionAfterExtension "CustomScriptExtension" `
  -AutoUpgradeMinorVersion $True

# Update the scale set
Update-AzVmss -ResourceGroupName $vmScaleSetResourceGroup `
  -Name $vmScaleSetName `
  -VirtualMachineScaleSet $vmScaleSet

CLI 2.0 do Azure

Utilize az vmss extension set para adicionar a extensão Application Health à definição do modelo do conjunto de dimensionamento. A sequenciação de extensões requer a utilização da CLI 2.0.55 ou superior do Azure.

O exemplo seguinte adiciona a extensão Application Health ao modelo de conjunto de dimensionamento de um conjunto de dimensionamento baseado no Windows. A extensão do Application Health será aprovisionada após o aprovisionamento da Extensão de Script Personalizado, já definida no conjunto de dimensionamento.

az vmss extension set \
  --name ApplicationHealthWindows \
  --publisher Microsoft.ManagedServices \
  --version 1.0 \
  --resource-group <myVMScaleSetResourceGroup> \
  --vmss-name <myVMScaleSet> \
  --provision-after-extensions CustomScriptExtension \
  --settings ./extension.json

Resolução de problemas

Não consegue adicionar a extensão com dependências?

  1. Confirme que as extensões especificadas em provisionAfterExtensions estão definidas no modelo do conjunto de dimensionamento.
  2. Confirme que não estão a ser introduzidas dependências circulares. Por exemplo, a seguinte sequência não é permitida: ExtensionA –> ExtensionB –> ExtensionC –> ExtensionA
  3. Certifique-se de que todas as extensões em que assume dependências têm uma propriedade "definições" na extensão "propriedades". Por exemplo, se ExtentionB precisar de ser aprovisionado após ExtensionA, extensionA tem de ter o campo "settings" em ExtensionA "properties". Pode especificar uma propriedade "definições" vazia se a extensão não exigir quaisquer definições necessárias.

Não consegue remover extensões?

Certifique-se de que as extensões que estão a ser removidas não estão listadas em provisionAfterExtensions para quaisquer outras extensões.

Passos seguintes

Saiba como implementar a sua aplicação no Conjuntos de Dimensionamento de Máquinas Virtuais.