Sprawdzanie właściwości zasobów za pomocą skryptów wdrażania

W tym artykule opisano sposób użycia Bicep i skryptu wdrażania w celu wstrzymania wdrożenia do momentu, gdy właściwość zasobu zwróci określoną wartość. Technika ta pozwala upewnić się, że wdrożenie zakończy się sukcesem, jeśli wdrażany zasób zgłosi do Azure Resource Manager, że jest gotowy, mimo że zasoby bazowe jeszcze nie są. W takim przypadku wdrożony zasób nie jest jeszcze gotowy do interakcji z resztą wdrożenia, co oznacza, że wymagana jest pauza.

W tym artykule użyto scenariusza Azure Virtual WAN, aby zademonstrować technikę. Następujące pliki obejmują sprawdzanie zasobów i wstrzymywanie implementacji:

Możesz dostosować pliki do wdrożenia. Aby ci pomóc, moduł azResourceStateCheck.bicep jest sparametryzowany. Właściwość dependsOn jest używana w pliku orchestration.bicep, aby upewnić się, że wdrożenie modułu vwanvhcs.bicep zależy od wdrożenia modułu azResourceStateCheck.bicep.

Architecture

Diagram przedstawiający architekturę Bicep i skryptu wdrażania.

Pobierz plik programu Visio tej architektury.

Przejrzyj i pobierz przykłady kodu w usłudze GitHub dla tej architektury.

  1. Prześlij plik orchestration.bicep do Resource Manager w zakresie subskrypcji w celu jego wdrożenia.

    Note

    Możesz pobrać ten plik Bicep i inne pliki, które są używane w tym przykładzie, z katalogu infra/samples/deployment-scripts-property-check. Częściowa organizacja plików w repozytorium jest wyświetlana po prawej stronie diagramu architektury.

  2. Plik orchestration.bicep tworzy grupę zasobów na poziomie subskrypcji.

  3. Plik orchestration.bicep wdraża Virtual WAN i sieci wirtualne typu 'spoke'.

    • orchestration.bicep wdraża moduł vwan.bicep, który wdraża Virtual WAN w zakresie grupy zasobów.

    • orchestration.bicep wdraża moduł vnet.bicep, który wdraża sieci wirtualne w zakresie grupy zasobów.

    Sieci wirtualne Virtual WAN i typu spoke są wdrażane równolegle, ponieważ Bicep uważa je za niezależne od siebie. Zależności określają kolejność wdrożenia w aplikacji Bicep. Zasób jest wdrażany przed każdym zasobem, który jest od niego zależny. Aby uzyskać więcej informacji na temat zależności zasobów w Bicep, w tym jawnych i niejawnych zależności, zobacz Zależności zasobów w Bicep.

  4. Plik orchestration.bicep wdraża moduł vwanhub.bicep, który wdraża centrum Virtual WAN na poziomie grupy zasobów. Centrum zależy niejawnie od Virtual WAN, co oznacza, że wdrożenie centrum odbywa się dopiero po zakończeniu wdrażania Virtual WAN.

  5. Plik orchestration.bicep wdraża moduł azResourceStateCheck.bicep, który tworzy zarządzaną tożsamość przypisaną przez użytkownika i przypisuje rolę Czytelnika (RBAC) opartą na rolach usługi Azure do grupy zasobów.

  6. Moduł azResourceStateCheck.bicep wdraża zasób skryptu wdrażania.

  7. Zasób skryptu wdrażania używa tożsamości zarządzanej przypisanej przez użytkownika do uwierzytelniania Resource Manager. Następnie zasób uruchamia skrypt wdrażania programu PowerShell, Invoke-AzResourceStateCheck.ps1. Aby uzyskać więcej informacji na temat skryptów wdrażania, zobacz Use deployment scripts in Bicep (Używanie skryptów wdrażania w środowisku Bicep).

    Skrypt sonduje właściwość routingState centrum Virtual WAN, aby określić, czy wartość jest Provisioned:

    1. Jeśli wartość właściwości nie jest Provisioned, skrypt wstrzymuje się na czas określony przez parametr ustawiony w pliku orchestration.bicep i przekazywany do modułu azResourceStateCheck.bicep. Następnie skrypt ponownie sprawdza wartość właściwości routingState.

      Skrypt powtarza cykl wstrzymania i sprawdzania. Parametr w pliku orchestration.bicep określa maksymalną liczbę iteracji. Jeśli wartość właściwości nie jest Provisioned po maksymalnej liczbie iteracji, skrypt generuje wyjątek i kończy działanie, co powoduje zatrzymanie i niepowodzenie wdrożenia Bicep.

    2. Jeśli wartość właściwości to Provisioned, skrypt wdrożenia kończy działanie z kodem (0) powodzenia.

  8. Jeśli skrypt wdrożenia zakończy się pomyślnie, plik orchestration.bicep wdroży moduł vwanvhcs.bicep, który tworzy połączenia między wirtualnymi sieciami rozszytymi a węzłem sieci WAN Virtual.

    Definicja modułu vwanvhcs.bicep znajdującego się w orkiestracji.bicep ma klauzulę dependsOn, która powoduje, że vwanvhcs.bicep jawnie zależy od pomyślnego zakończenia modułu azResourceStateCheck.bicep. W związku z tym połączenia są tworzone tylko wtedy, gdy routingState właściwość jest Provisioned.

    Moduł vwanvhcs.bicep wdraża sekwencyjnie połączenia centrum Virtual WAN, a nie równolegle, ponieważ wdrożenie równoległe nie jest obsługiwane dla pojedynczego centrum Virtual WAN. Aby ustawić rozmiar partii na 1, moduł używa dekoratora Bicep batchSize, @batchSize(1). Ten dekorator gwarantuje, że łącza są wdrażane jedno po drugim.

Szczegóły scenariusza

Kluczowymi częściami tej architektury jest moduł azResourceStateCheck.bicep, który wdraża zasób skryptu wdrażania, oraz skojarzony skrypt wdrożenia Invoke-AzResourceStateCheck.ps1, który jest plikiem programu PowerShell. Moduł używa skryptu wdrażania do sprawdzania wartości właściwości zasobu. W tym przykładzie zasób jest hubem usługi Virtual WAN.

Można użyć dependsOn, aby jeden moduł był jawnie zależny od innego, ponieważ to środowisko jest wdrażane z jednego pliku, który używa modułów Bicep. W tym przykładzie dependsOn moduł vwanvhcs.bicep zależy od modułu azResourceStateCheck.bicep.

Poniższy fragment z orchestration.bicep pokazuje dependsOn w użyciu:

@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
  }
}

Sprawdzanie zasobów jest wymagane, ponieważ wdrożone centra Virtual WAN nie są gotowe do użycia, dopóki właściwość routingState ma wartość Provisioned. Virtualne koncentratory WAN zgłaszają pomyślne wdrożenie do Menedżera zasobów, aby silnik wdrażania mógł kontynuować wdrażanie. Nowe centrum Virtual WAN staje się operacyjne po skonfigurowaniu routera koncentratora Virtual WAN w utworzonym koncentratorze. Ten proces trwa około 15 minut. To zachowanie można zobaczyć na poniższym zrzucie ekranu nowego centrum Virtual WAN. Zrzut ekranu przedstawia stan centrum Succeeded, ale stan routingu Provisioning.

Zrzut ekranu niedawno wdrożonego centrum Virtual WAN. Stan centrum to: powiodło się, a stan routingu to: inicjowanie.

Jeśli spróbujesz wdrożyć moduł vwanvhcs.bicep zanim wartość routingState wyniesie Provisioned, tworzenie połączenia nie powiedzie się, a całe wdrożenie zakończy się niepowodzeniem. Dopóki router nie zostanie zaaprowizowany, ponowne wdrożenie również nie powiedzie się.

Poniższy zrzut ekranu przedstawia przykład dziennika wdrażania skryptów podczas sprawdzania routingState centrum sieci WAN wirtualnej. W dzienniku są wyświetlane powtarzające się kontrole właściwości, które zwracają wartość inną niż Provisioned.

Screenshot przedstawiający skrypt wdrożenia sondujący właściwość Virtual WAN hub routingState.

Poniższy zrzut ekranu pokazuje, że wartość zmienia się na Provisioned.

Zrzut ekranu przedstawiający ukończenie skryptu wdrażania, gdy właściwość routingState centrum sieci Virtual WAN zmienia się na Provisioned.

Jeśli wartość nie zmieni się na Provisioned po maksymalnej liczbie iteracji, skrypt generuje wyjątek, który sygnalizuje niepowodzenie zasobu skryptu Resource Manager. Silnik wdrażania Resource Manager ulega awarii i przerywa wdrożenie, ponieważ wyjątek sugeruje istnienie problemu z zasobem Azure, którego rozwiązanie wymaga diagnostyki. Aby uzyskać więcej informacji, zobacz następujący skrypt 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

Microsoft utrzymuje ten artykuł. Następujący współautorzy napisali ten artykuł.

Główny autor:

  • Jack Tracey | Starszy architekt rozwiązań w chmurze

Inny współautor:

Aby wyświetlić niepubliczne profile serwisu LinkedIn, zaloguj się do serwisu LinkedIn.

Następne kroki