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

Este artigo descreve como usar o Bicep e um script de implementação para pausar uma implementação até que uma propriedade de recurso devolva um valor específico. Pode usar esta técnica para garantir que uma implementação tem sucesso se o recurso implementado reportar ao Azure Resource Manager que está pronto, mas os recursos subjacentes não estão. Neste caso, o recurso implementado ainda não está pronto para interagir com o resto da implementação, o que significa que é necessária uma pausa.

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

Você pode adaptar os arquivos para sua implantação. Para te ajudar, o módulo azResourceStateCheck.bicep está parametrizado. A dependsOn propriedade é usada no orchestration.bicep para garantir que a implementação do módulo vwanvhcs.bicep depende da implementação do módulo azResourceStateCheck.bicep.

Architecture

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

Descarregue um ficheiro Visio desta arquitetura.

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

  1. Submeta o ficheiro orchestration.bicep para implementação no Resource Manager no âmbito da subscrição.

    Note

    Pode obter este ficheiro Bicep e os outros ficheiros usados neste exemplo no diretório infra/samples/deployment-scripts-property-check. Uma organização parcial dos ficheiros no repositório aparece no lado direito do diagrama de arquitetura.

  2. O ficheiro orchestration.bicep cria um grupo de recursos no âmbito da subscrição.

  3. O ficheiro 'orchestration.bicep' implementa a WAN Virtual e as redes virtuais 'spokes'.

    • O Orchestration.Bicep implementa o módulo vwan.Bicep, que implementa o WAN Virtual no âmbito do grupo de recursos.

    • O Orchestration.Bicep implementa o módulo Vnet.Bicep, que implementa as redes virtuais no âmbito do grupo de recursos.

    A WAN Virtual e as redes virtuais spoke são implementadas em paralelo porque a Bicep as considera independentes uma da outra. 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 ficheiro orchestration.bicep implementa o módulo vwanhub.bicep, que implementa o hub WAN Virtual no âmbito do grupo de recursos. O hub depende implicitamente da WAN Virtual, o que significa que a implementação do hub só ocorre após a conclusão da implementação da WAN Virtual.

  5. O ficheiro orchestration.bicep implementa o módulo azResourceStateCheck.bicep, que cria uma identidade gerida atribuída pelo utilizador e atribui o papel de Leitor de Controlo de Acesso Baseado em Funções do Azure (RBAC) ao grupo de recursos.

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

  7. O recurso do script de implementação utiliza a identidade gerida atribuída pelo utilizador para a autenticação do Resource Manager. O recurso executa então o script de implementação PowerShell, Invoke-AzResourceStateCheck.ps1. Para obter mais informações sobre scripts de implantação, consulte Usar scripts de implantação no Bicep.

    O script interroga 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 durante um período especificado por um parâmetro definido no ficheiro orchestration.bicep e é passado para o módulo azResourceStateCheck.bicep. O script verifica então novamente o valor da routingState propriedade.

      O guião repete o ciclo de pausa e verificação. Um parâmetro no ficheiro 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 gera uma exceção e sai, o que faz com que o restante da implementação da Bicep pare e falhe.

    2. Se o valor da propriedade for Provisioned, o script de implementação sai com um código (0)de sucesso .

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

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

    O módulo vwanvhcs.bicep implementa as ligações do hub WAN Virtual sequencialmente, em vez de em paralelo, porque a implementação paralela não é suportada para um único hub WAN Virtual. Para definir o tamanho do lote para 1, o módulo utiliza o decorador Bicep batchSize, @batchSize(1). Este decorador assegura que as conexões são instaladas uma de cada vez.

Detalhes do cenário

As partes principais desta arquitetura são o módulo azResourceStateCheck.bicep, que implementa o recurso de script de implementação, e o script de implementação associado Invoke-AzResourceStateCheck.ps1, que é um ficheiro 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 WAN Virtual.

Podes usar dependsOn para fazer com que um módulo dependa explicitamente de outro porque este ambiente é implementado a partir de um único ficheiro que usa Bicep módulos. Neste exemplo, dependsOn faz com que o módulo vwanvhcs.bicep dependa do módulo azResourceStateCheck.bicep.

O seguinte excerto do orchestration.bicep mostra o uso de dependsOn:

@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 é obrigatória porque os hubs de WAN Virtual implementados não estão prontos para uso até que a propriedade routingState tenha o valor de Provisioned. Os hubs WAN Virtual reportam a implementação bem-sucedida ao Resource Manager para que o motor de implementação continue a implementar. Um novo hub WAN Virtual torna-se operacional após o router hub WAN Virtual ser provisionado no hub criado. Este processo demora cerca de 15 minutos. Este comportamento pode ser visto na captura de ecrã seguinte de um novo hub WAN Virtual. A captura de ecrã mostra o estado do hub de Succeeded mas o estado de roteamento de Provisioning.

Captura de ecrã de um hub WAN Virtual recentemente implementado. O estado do hub é Bem-sucedido e o estado de routing é Em provisionamento.

Se tentar implementar o módulo vwanvhcs.bicep antes do valor routingState ser Provisioned, a criação de ligação e a implementação global falham. Até que o router seja provisionado, as tentativas de reimplementação também falham.

A captura de ecrã seguinte mostra um exemplo do registo do script de implementação durante as verificações routingState do hub WAN Virtual. O registo mostra verificações repetidas da propriedade que retornam um valor diferente de Provisioned.

Captura de ecrã que mostra o script de implementação a interrogar a propriedade routingState do WAN Virtual Hub.

A captura de ecrã seguinte mostra que o valor muda para Provisioned.

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

Se o valor não mudar para Provisioned após o número máximo de iterações, o script gera uma exceção, que sinaliza a falha do recurso do script para Resource Manager. O motor de implementação do Resource Manager falha e para a implementação porque a exceção indica que há um problema com o recurso do Azure que exige resolução de problemas. Para obter mais informações, consulte o seguinte script Invoke-AzResourceStateCheck.ps1.

[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 seguintes colaboradores escreveram este artigo.

Autor principal:

Outros contribuidores:

Para ver perfis não públicos do LinkedIn, faça login no LinkedIn.

Passos seguintes