Condividi tramite


Creare runbook modulari in Automazione

In Automazione di Azure è buona prassi scrivere runbook riutilizzabili e modulari con una funzione discreta chiamata da altri runbook. Un runbook padre chiama spesso uno o più runbook figlio per eseguire la funzionalità richiesta.

Esistono due modi per chiamare un runbook figlio: inline o tramite un cmdlet. La tabella seguente riepiloga le differenze per consentire di decidere quale sia il modo migliore in base agli scenari.

Incorporato Cmdlet
Mansione I runbook figlio vengono eseguiti nello stesso processo dell’elemento padre. Viene creato un processo separato per il runbook figlio.
Esecuzione Il runbook padre attende il completamento del runbook figlio prima di continuare. Il runbook padre continua subito dopo l'avvio del runbook figlio o attende il completamento del processo figlio.
Output Il runbook padre può ottenere output direttamente dal runbook figlio. Il runbook padre deve recuperare l'output dal processo del runbook figlio o può ottenere direttamente l'output dal runbook figlio.
Parametri I valori per i parametri di runbook figlio vengono specificati separatamente e possono utilizzare qualsiasi tipo di dati. I valori dei parametri dei runbook figlio devono essere raggruppati in un'unica tabella hash. Questa tabella hash può contenere solo tipi di dati semplici, matrice e oggetto che usano la serializzazione JSON.
Account di Automazione Il runbook padre può usare solo un runbook figlio nello stesso account di Automazione. I runbook padre possono usare un runbook figlio da qualsiasi account di Automazione, dalla stessa sottoscrizione di Azure, e anche da una sottoscrizione diversa con cui si ha una connessione.
Pubblicazione Il runbook figlio deve essere pubblicato prima della pubblicazione del runbook padre. Il runbook figlio viene pubblicato in qualsiasi momento precedente all'avvio del runbook padre.

Chiamare un runbook figlio usando l'esecuzione inline

Per chiamare un runbook inline da un altro runbook, usare il nome del runbook e specificare i valori per i relativi parametri, esattamente come si fa per un'attività o un cmdlet. Tutti i runbook nello stesso account di Automazione sono disponibili per tutti gli altri e possono essere usati in questo modo. Il runbook padre attende il completamento del runbook figlio prima di passare alla riga successiva e riceve direttamente l'eventuale output.

Quando si chiama un runbook inline, questo viene eseguito nello stesso processo del runbook padre. Nella cronologia processo non è indicato il runbook figlio. Eventuali eccezioni e output del flusso dal runbook figlio vengono associati al runbook padre. Questo comportamento ha come risultato un minor numero di processi e semplifica la traccia e la risoluzione dei problemi di questi.

Quando viene pubblicato un runbook, tutti i runbook figlio chiamati devono già essere pubblicati. Il motivo è che quando compila un runbook Automazione di Azure crea un'associazione con i runbook figlio. Se i runbook figlio non sono stati ancora pubblicati, il runbook padre viene pubblicato apparentemente in modo corretto, ma genera un'eccezione quando viene avviato.

Se si genera un’eccezione, è possibile ripubblicare il runbook padre in modo che faccia riferimento in modo corretto ai runbook figlio. Non è necessario ripubblicare il runbook padre se uno o più runbook figlio sono stati modificati, perché l'associazione è già stata creata.

I dati dei parametri di un runbook figlio chiamato inline possono essere di qualsiasi tipo, inclusi oggetti complessi. Non viene eseguita alcuna serializzazione JSON, come invece avviene quando si avvia il runbook usando il portale di Azure o il cmdlet Start-AzAutomationRunbook.

Tipi di runbook

Attualmente è supportato PowerShell 5.1 e solo alcuni tipi di runbook possono chiamarsi tra loro:

  • Un runbook PowerShell e un runbook grafico possono chiamarsi reciprocamente inline, perché entrambi si basano su PowerShell.
  • Un runbook del flusso di lavoro di PowerShell e un runbook del flusso di lavoro di PowerShell grafico possono chiamarsi reciprocamente inline, perché entrambi si basano sul flusso di lavoro di PowerShell.
  • I tipi PowerShell e i tipi del flusso di lavoro di PowerShell non possono chiamarsi reciprocamente inline. Devono usare Start-AzAutomationRunbook.

Importante

L'esecuzione di script figlio tramite .\child-runbook.ps1 non è supportata in PowerShell 7.1 e PowerShell 7.2.Soluzione alternativa: usare Start-AutomationRunbook ( (cmdlet interno) o Start-AzAutomationRunbook (dal modulo Az.Automation) per avviare un altro runbook dal runbook padre.

L'ordine di pubblicazione dei runbook è rilevante solo per i runbook del flusso di lavoro di PowerShell e i runbook del flusso di lavoro di PowerShell grafici.

Quando un runbook chiama un runbook figlio grafico o del flusso di lavoro di PowerShell tramite esecuzione inline, usa il nome del runbook. Il nome deve iniziare con .\\ per specificare che lo script è nella directory locale.

Esempio

L'esempio seguente avvia un runbook figlio di test che accetta un oggetto complesso, un valore intero e un valore Booleano. L'output del runbook figlio viene assegnato a una variabile. In questo caso, il runbook figlio è un runbook del flusso di lavoro PowerShell.

$vm = Get-AzVM -ResourceGroupName "LabRG" -Name "MyVM"
$output = PSWF-ChildRunbook -VM $vm -RepeatCount 2 -Restart $true

Ecco lo stesso esempio, ma con un runbook PowerShell come elemento figlio.

$vm = Get-AzVM -ResourceGroupName "LabRG" -Name "MyVM"
$output = .\PS-ChildRunbook.ps1 -VM $vm -RepeatCount 2 -Restart $true

Avviare un runbook figlio tramite un cmdlet

Importante

Se il runbook chiama un runbook figlio tramite il cmdlet Start-AzAutomationRunbook con il parametro Wait e il runbook figlio produce un risultato oggetto, l'operazione potrebbe generare un errore. Per risolvere l'errore, vedere Runbook figlio con output dell'oggetto. In questo articolo viene illustrato come implementare la logica per eseguire il polling dei risultati tramite il cmdlet Get-AzAutomationJobOutputRecord.

Per avviare un runbook, è possibile usare Start-AzAutomationRunbook, come descritto in Avviare un runbook con Windows PowerShell. Sono disponibili due modalità di utilizzo di questo cmdlet:

  • Il cmdlet restituisce l'ID del processo quando viene creato il processo per il runbook figlio.
  • Il cmdlet attende il completamento del processo figlio e restituisce l'output del runbook figlio. Lo script abilita questa modalità specificando il parametro Wait.

Il processo di un runbook figlio avviato con un cmdlet viene eseguito separatamente dal processo del runbook padre. Questo comportamento produce più processi rispetto all'avvio del runbook inline e rende più difficile il monitoraggio di tali processi. Il runbook padre può avviare più runbook figlio in modo asincrono senza attendere che ognuno di essi finisca. Per questa esecuzione parallela che chiama i runbook figlio inline, il runbook padre deve usare la parola chiave parallela.

L'output dei runbook figlio non viene restituito al runbook padre in modo affidabile a causa della temporizzazione. Anche $VerbosePreference, $WarningPreference e altre variabili potrebbero non essere propagate ai runbook figlio. Per evitare questi problemi, è possibile avviare i runbook figlio come processi di Automazione separati usando Start-AzAutomationRunbook con il parametro Wait. Questa tecnica blocca il runbook padre fino a quando non è finito il runbook figlio.

Se non si vuole che il runbook padre rimanga bloccato in attesa, è possibile avviare il runbook figlio usando Start-AzAutomationRunbook senza il parametro Wait. In questo caso, il runbook deve usare Get-AzAutomationJob per attendere il completamento del processo. Deve anche usare Get-AzAutomationJobOutput e Get-AzAutomationJobOutputRecord per recuperare i risultati.

I parametri per un runbook figlio avviato con un cmdlet vengono resi disponibili sotto forma di tabella hash, come descritto in Parametri di runbook. È possibile usare solo tipi di dati semplici. Se il runbook dispone di un parametro con un tipo di dati complessi, deve essere chiamato inline.

Il contesto della sottoscrizione potrebbe andare perso quando si avviano i runbook figlio come processi separati. Perché il runbook figlio possa eseguire i cmdlet del modulo Az per una sottoscrizione di Azure specifica, il runbook figlio deve eseguire l'autenticazione in tale sottoscrizione indipendentemente dal runbook padre.

Se i processi nello stesso account di Automazione usano più sottoscrizioni, la selezione di una sottoscrizione in un processo può cambiare il contesto della sottoscrizione attualmente selezionata anche per altri processi. Per evitare questa situazione, usare Disable-AzContextAutosave -Scope Process all'inizio di ogni runbook. Questa azione salva solo il contesto dell'esecuzione del runbook.

Esempio

L'esempio seguente illustra l’avvio di un runbook figlio con parametri e quindi attende che finisca usando il cmdlet Start-AzAutomationRunbook con il parametro Wait. Una volta finito il runbook figlio, l'esempio raccoglie l'output del cmdlet dal runbook figlio. Per usare Start-AzAutomationRunbook lo script deve eseguire l'autenticazione alla sottoscrizione di Azure.

# Ensure that the runbook does not inherit an AzContext
Disable-AzContextAutosave -Scope Process

# Connect to Azure with system-assigned managed identity
$AzureContext = (Connect-AzAccount -Identity).context

# set and store context
$AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext

$params = @{"VMName"="MyVM";"RepeatCount"=2;"Restart"=$true}

Start-AzAutomationRunbook `
    -AutomationAccountName 'MyAutomationAccount' `
    -Name 'Test-ChildRunbook' `
    -ResourceGroupName 'LabRG' `
    -DefaultProfile $AzureContext `
    -Parameters $params -Wait

Se si vuole che il runbook venga eseguito con l'identità gestita assegnata dal sistema, lasciare invariato il codice. Se si preferisce usare un'identità gestita assegnata dall'utente, procedere come illustrato di seguito:

  1. Rimuovere $AzureContext = (Connect-AzAccount -Identity).context dalla riga 5.
  2. Sostituirlo con $AzureContext = (Connect-AzAccount -Identity -AccountId <ClientId>).context e
  3. Immettere l'ID client.

Passaggi successivi