Usar scripts de implantação para verificar as propriedades do recurso

Este artigo descreve como usar Bicep e um script de implantação para pausar uma implantação até que uma propriedade de recurso retorne um valor específico. Você pode usar essa técnica para garantir que uma implantação seja bem-sucedida se o recurso implantado informar ao Azure Resource Manager que está pronto, mas os recursos subjacentes não estiverem. Nesse caso, o recurso implantado ainda não está pronto para interagir com o restante da implantação, o que significa que uma pausa é necessária.

Este artigo usa um cenário WAN Virtual do Azure para demonstrar a técnica. Os seguintes arquivos incluem uma verificação de recursos e uma implementação de pausa:

Você pode adaptar os arquivos para sua implantação. Para ajudar você, o módulo azResourceStateCheck.bicep é parametrizado. A dependsOn propriedade é usada em orchestration.bicep para garantir que a implantação do módulo vwanvhcs.bicep dependa da implantação do módulo azResourceStateCheck.bicep.

Architecture

Diagrama que mostra a arquitetura do Bicep e do script de implantação.

Carrege um arquivo Visio desta arquitetura.

Examine e baixe os exemplos de código no GitHub para essa arquitetura.

  1. Envie o arquivo orchestration.bicep para implantação no Resource Manager no escopo da assinatura.

    Note

    Você pode obter esse arquivo Bicep e os outros arquivos usados para este exemplo no diretório infra/samples/deployment-scripts-property-check directory. Uma organização parcial dos arquivos no repositório aparece no lado direito do diagrama de arquitetura.

  2. O arquivo orchestration.bicep cria um grupo de recursos no escopo da assinatura.

  3. O arquivo orchestration.bicep implanta o WAN Virtual e as redes virtuais spoke.

    • orchestration.bicep implanta o módulo vwan.bicep, que, por sua vez, implanta a Rede WAN Virtual no escopo do grupo de recursos.

    • orchestration.bicep implanta o módulo vnet.bicep, que, por sua vez, implanta as redes virtuais no escopo do grupo de recursos.

    As redes virtuais WAN Virtual e spoke são implantadas em paralelo porque Bicep as considera independentes umas das outras. As dependências determinam a ordem de implantação no Bicep. Um recurso é implantado antes de qualquer recurso que dependa dele. Para obter mais informações sobre dependências de recursos no Bicep, incluindo dependências explícitas e implícitas, consulte dependências de recursos no Bicep.

  4. O arquivo orchestration.bicep implanta o módulo vwanhub.bicep, que implanta o hub WAN Virtual no escopo do grupo de recursos. O hub depende implicitamente do WAN Virtual, o que significa que a implantação do hub ocorre somente após a conclusão da implantação do WAN Virtual.

  5. O arquivo orchestration.bicep implanta o módulo azResourceStateCheck.bicep, que cria uma identidade gerenciada atribuída pelo usuário e atribui a função de leitor do RBAC (controle de acesso baseado em função) Azure ao grupo de recursos.

  6. O módulo azResourceStateCheck.bicep implanta o recurso de script de implantação.

  7. O recurso de script de implantação usa a identidade gerenciada atribuída pelo usuário para autenticação do Azure Resource Manager. Em seguida, o recurso executa o script de implantação do PowerShell, Invoke-AzResourceStateCheck.ps1. Para obter mais informações sobre scripts de implantação, consulte Usar scripts de implantação no Bicep.

    O script sonda a propriedade WAN Virtual hub routingState para determinar se o valor é Provisioned:

    1. Se o valor da propriedade não for Provisioned, o script pausa por uma duração especificada por parâmetros definidos no arquivo orchestration.bicep e é passado ao módulo azResourceStateCheck.bicep. Em seguida, o script verifica o valor da routingState propriedade novamente.

      O script repete o ciclo de pausa e verificação. Um parâmetro no arquivo orchestration.bicep determina o número máximo de iterações. Se o valor da propriedade não for Provisioned após o número máximo de iterações, o script gerará uma exceção e sairá, o que fará com que as implantações Bicep restantes parem e falhem.

    2. Se o valor da propriedade for Provisioned, o script de implantação sairá com um código de êxito (0).

  8. Se o script de implantação for bem-sucedido, o arquivo orchestration.bicep implantará o módulo vwanvhcs.bicep, que cria as conexões entre as redes virtuais spoke e o hub WAN Virtual.

    A definição do módulo vwanvhcs.bicep que está em orchestration.bicep tem uma dependsOn cláusula que faz com que vwanvhcs.bicep dependa explicitamente da conclusão bem-sucedida do módulo azResourceStateCheck.bicep. Portanto, as conexões serão criadas somente se a routingState propriedade for Provisioned.

    O módulo vwanvhcs.bicep implanta as conexões de hub WAN Virtual sequencialmente, em vez de paralelamente, porque a implantação paralela não tem suporte para um único hub WAN Virtual. Para definir o tamanho do lote como 1, o módulo usa o decorador Bicep batchSize, @batchSize(1). Esse decorador garante que as conexões sejam implantadas uma de cada vez.

Detalhes do cenário

As principais partes dessa arquitetura são o módulo azResourceStateCheck.bicep, que implanta o recurso de script de implantação e o script de implantação associado Invoke-AzResourceStateCheck.ps1, que é um arquivo do PowerShell. O módulo usa o script de implantação para verificar o valor de uma propriedade de recurso. Neste exemplo, o recurso é um hub de WAN Virtual.

Você pode usar dependsOn para fazer com que um módulo dependa explicitamente de outro porque esse ambiente é implantado a partir de um único arquivo que usa módulos Bicep. Neste exemplo, dependsOn faz com que o módulo vwanvhcs.bicep dependa do módulo azResourceStateCheck.bicep.

O trecho a seguir de orchestration.bicep mostra dependsOn sendo utilizado:

@description('The API version of the Azure Resource you need to use to check the state of a property.')
param parAzResourceApiVersion string = '2022-01-01'

@description('The property of the resource that you need to check. This is a property inside the `properties` bag of the resource that's captured from a GET call to the Resource ID.')
param parAzResourcePropertyToCheck string = 'routingState'

@description('The value of the property of the resource that you need to check.')
param parAzResourceDesiredState string = 'Provisioned'

@description('The duration that the deployment script waits between check or polling requests to check the property and its state, if it is not in its desired state. The duration defaults to `30` seconds.')
param parWaitInSecondsBetweenIterations int = 30

module modVWANHub 'modules/vwanHub.bicep' = {
  scope: rsg
  name: 'deployVWANHub'
  params: {
    region: region
    regionNamePrefix: regionNamePrefix
    defaultTags: defaultTags
    vwanHubCIDR: vwanHubCIDR
    vwanName: modVWAN.outputs.vwanName
  }
}

module modVWANHubRouterCheckerDeploymentScript 'modules/azResourceStateCheck.bicep' = {
  scope: rsg
  name: 'deployVWANHubRouterChecker'
  params: {
    parLocation: region
    parAzResourceId: modVWANHub.outputs.outVwanVHubId
    parAzResourceApiVersion: parAzResourceApiVersion
    parAzResourcePropertyToCheck: parAzResourcePropertyToCheck
    parAzResourceDesiredState: parAzResourceDesiredState
    parMaxIterations: parMaxIterations
    parWaitInSecondsBetweenIterations: parWaitInSecondsBetweenIterations
  }
}

module modVWanVhubVnetConnections 'modules/vwanVhcs.bicep' = {
  dependsOn: [
    modVWANHubRouterCheckerDeploymentScript
  ]
  scope: rsg
  name: 'deployConnectVnetsToVWANVHub'
  params: {
    vnets: vnets
    regionNamePrefix: regionNamePrefix
  }
}

A verificação de recursos é necessária porque os hubs WAN Virtual implantados não estão prontos para uso até que a propriedade routingState tenha o valor de Provisioned. Hubs do WAN Virtual relatam ao Resource Manager a implantação bem-sucedida para que o mecanismo de implantação possa continuar o processo. Um novo hub WAN Virtual se torna operacional depois que o roteador de hub WAN Virtual é provisionado no hub criado. Esse processo leva cerca de 15 minutos. Esse comportamento pode ser visto na captura de tela a seguir de um novo hub de WAN Virtual. A captura de tela mostra um status de hub de Succeeded , mas um status de roteamento de Provisioning.

Captura de tela de um hub de WAN Virtual recém-implantado. O status do hub é Concluído e o status de roteamento é Provisionamento.

Se você tentar implantar o módulo vwanvhcs.bicep antes que o valor sejaroutingState, a Provisioned criação da conexão falhará e a implantação geral falhará. Até que o roteador seja provisionado, as tentativas de reimplantação também falharão.

A captura de tela a seguir mostra um exemplo do log de script de implantação durante as verificações do hub do WAN Virtual. O log mostra verificações repetidas da propriedade que retornam um valor diferente de Provisioned.

Captura de tela que mostra o script de implantação consultando a propriedade routingState do hub WAN Virtual.

A captura de tela a seguir mostra que o valor é alterado para Provisioned.

Captura de tela que mostra a conclusão do script de implantação quando a propriedade WAN Virtual hub routingState muda para Provisioned.

Se o valor não for alterado para Provisioned após o número máximo de iterações, o script gerará uma exceção, o que sinalizará a falha do recurso de script para Resource Manager. O mecanismo de implantação Resource Manager falha e interrompe a implantação porque a exceção sugere que há um problema com o recurso Azure que requer solução de problemas. Para obter mais informações, consulte o script de Invoke-AzResourceStateCheck.ps1 a seguir.

[CmdletBinding()]
param (
  [string]
  $azResourceResourceId,

  [string]
  $apiVersion = "2022-05-01",

  [string]
  $azResourcePropertyToCheck = "provisioningState",

  [string]
  $azResourceDesiredState = "Provisioned",

  [int]
  $waitInSecondsBetweenIterations = 30,

  [int]
  $maxIterations = 30
)

$totalTimeoutCalculation = $waitInSecondsBetweenIterations * $maxIterations

$azResourcePropertyExistenceCheck = Invoke-AzRestMethod -Method GET -Path "$($azResourceResourceId)?api-version=$($apiVersion)"

if ($azResourcePropertyExistenceCheck.StatusCode -ne "200") {
  $DeploymentScriptOutputs["azResourcePropertyState"] = "Not Found"
  throw "Unable to get Azure Resource - $($azResourceResourceId). Likely it doesn't exist. Status code: $($azResourcePropertyExistenceCheck.StatusCode) Error: $($azResourcePropertyExistenceCheck.Content)"
}

$azResourcePropertyStateResult = "Unknown"
$iterationCount = 0

do {
  $azResourcePropertyStateGet = Invoke-AzRestMethod -Method GET -Path "$($azResourceResourceId)?api-version=$($apiVersion)"
  $azResourcePropertyStateJsonConverted = $azResourcePropertyStateGet.Content | ConvertFrom-Json -Depth 10
  $azResourcePropertyStateResult = $azResourcePropertyStateJsonConverted.properties.$($azResourcePropertyToCheck)

  if ($azResourcePropertyStateResult -ne $azResourceDesiredState) {
    Write-Host "Azure Resource Property ($($azResourcePropertyToCheck)) is not in $($azResourceDesiredState) state. Waiting $($waitInSecondsBetweenIterations) seconds before checking again. Iteration count: $($iterationCount)"
    Start-Sleep -Seconds $waitInSecondsBetweenIterations
    $iterationCount++
  }
} while (
  $azResourcePropertyStateResult -ne $azResourceDesiredState -and $iterationCount -ne $maxIterations
)

if ($azResourcePropertyStateResult -eq $azResourceDesiredState) {
  Write-Host "Azure Resource Property ($($azResourcePropertyToCheck)) is now in $($azResourceDesiredState) state."
  $DeploymentScriptOutputs["azResourcePropertyState"] = "$($azResourceDesiredState)"
}

if ($iterationCount -eq $maxIterations -and $azResourcePropertyStateResult -ne $azResourceDesiredState) {
  $DeploymentScriptOutputs["azResourcePropertyState"] = "Azure Resource Property ($($azResourcePropertyToCheck)) is still not in desired state of $($azResourceDesiredState). Timeout reached of $($totalTimeoutCalculation) seconds."
  throw "Azure Resource Property ($($azResourcePropertyToCheck)) is still not in $($azResourceDesiredState) state after $($totalTimeoutCalculation) seconds."
}

Contributors

A Microsoft mantém este artigo. Os colaboradores a seguir escreveram este artigo.

Autor principal:

  • Jack Tracey | Arquiteto sênior de soluções de nuvem

Outro colaborador:

Para ver perfis de LinkedIn não públicos, entre em LinkedIn.

Próximas Etapas