從 Webhook 啟動 Runbook

Webhook 可讓外部服務在 Azure 自動化中,透過單一 HTTP 要求啟動特定的 Runbook。 外部服務包括 Azure DevOps Services、GitHub、Azure 監視器記錄,以及自訂應用程式。 這類服務可以使用 Webhook 來啟動 Runbook,而不實作完整的Azure 自動化 API。 您可以將 Webhook 與啟動 runbook 的其他方法進行比較,方法是在 Azure 自動化 中啟動 Runbook。

WebhooksOverview

若要瞭解使用 Webhook 的 TLS 1.2 或更高版本的用戶端需求,請參閱 TLS 1.2 或更高版本以取得Azure 自動化

Webhook 屬性

下表描述您必須為 Webhook 設定的屬性。

屬性 描述
名稱 Webhook 的名稱。 您可以提供您想要的任何名稱,因為它不會公開給用戶端。 該名稱僅供您用來識別 Azure 自動化中的 Runbook。 最佳做法是您給予 Webhook 的名稱應該與要使用它的用戶端相關。
URL Webhook 的 URL。 這是唯一性的位址,即用戶端用來呼叫 HTTP POST 以啟動連結至 Webhook 的 Runbook。 當您建立 Webhook 時其會自動產生。 您無法指定自訂 URL。

URL 包含可讓協力廠商系統不需進一步驗證即可叫用 Runbook 的安全性權杖。 基於此原因,您應該將 URL 視為密碼。 基於安全性考慮,您只能在建立 Webhook 時檢視Azure 入口網站中的 URL。 記下安全位置中的 URL 以供日後使用。
到期日期 Webhook 的到期日,在此之後就無法再使用。 您可以在 Webhook 建立後修改到期日,只要 Webhook 尚未過期即可。
已啟用 設定,指出建立 Webhook 時是否預設為啟用。 如果您將此屬性設定為 Disabled,則沒有任何用戶端可以使用 Webhook。 您可以在建立 Webhook 或建立 Webhook 之後的任何其他時間設定這個屬性。

Webhook 啟動 Runbook 時所使用的參數

Webhook 可以定義 Runbook 參數的值,這些參數會在 Runbook 啟動時使用。 Webhook 必須包含任何必要 Runbook 參數的值,而且可以包含選擇性參數的值。 即使 Webhook 建立之後,也可以修改設定為 Webhook 的參數值。 連結至單一 Runbook 的多個 Webhook 可以使用不同的 Runbook 參數值。 當用戶端使用 Webhook 啟動 Runbook 時,它無法覆寫 Webhook 中定義的參數值。

若要從用戶端接收資料,Runbook 支援稱為 WebhookData 的單一參數。 此參數會定義物件,其中包含用戶端在 POST 要求中所包含的資料。

WebhookData properties

參數 WebhookData 具有下列屬性:

屬性 說明
WebhookName Webhook 的名稱。
RequestHeader 包含傳入 POST 要求的標頭的雜湊表。
RequestBody 傳入 POST 要求的本文。 此本文會保留任何資料格式,例如字串、JSON、XML 或表單編碼。 必須寫入 Runbook,才能使用預期的資料格式。

不支援 參數所需的 WebhookData Webhook 設定,而且不需要 Runbook 才能接受它。 如果 Runbook 未定義 參數,則會忽略從用戶端傳送之要求的任何詳細資料。

注意

呼叫 Webhook 時,用戶端應該一律儲存任何參數值,以防呼叫失敗。 如果發生網路中斷或連線問題,應用程式就無法擷取失敗的 Webhook 呼叫。

如果您在建立 Webhook 時指定 值 WebhookData ,當 Webhook 使用來自用戶端 POST 要求的資料啟動 Runbook 時,就會覆寫該值。 即使應用程式未在要求本文中包含任何資料,也會發生這種情況。

如果您啟動使用 Webhook 以外的機制定義的 WebhookData Runbook,您可以提供 Runbook 可辨識的值 WebhookData 。 此值應該是與 參數具有相同 屬性 WebhookData 的物件,因此 Runbook 可以使用它,就像它與 Webhook 所傳遞的實際 WebhookData 物件一樣。

例如,如果您要從 Azure 入口網站 啟動下列 Runbook,而且想要傳遞一些範例 Webhook 資料進行測試,則必須在使用者介面中以 JSON 傳遞資料。

WebhookData parameter from UI

針對下一個 Runbook 範例,讓我們為 定義下列屬性 WebhookData

  • WebhookName :MyWebhook
  • RequestBody *[{'ResourceGroup': 'myResourceGroup','Name': 'vm01'},{'ResourceGroup': 'myResourceGroup','Name': 'vm02'}]*

現在,我們會在 UI 中傳遞 WebhookData 參數的下列 JSON 物件。 此範例使用歸位字元和分行符號,符合從 Webhook 傳入的格式。

{"WebhookName":"mywebhook","RequestBody":"[\r\n {\r\n \"ResourceGroup\": \"vm01\",\r\n \"Name\": \"vm01\"\r\n },\r\n {\r\n \"ResourceGroup\": \"vm02\",\r\n \"Name\": \"vm02\"\r\n }\r\n]"}

Start WebhookData parameter from UI

注意

Azure 自動化使用 Runbook 作業記錄所有輸入參數的值。 因此,Webhook 要求中用戶端所提供的任何輸入都會記錄,並可供任何可存取自動化作業的人員使用。 基於這個理由,您應該謹慎在 Webhook 呼叫中包含敏感性資訊。

Webhook 安全性

Webhook 的安全性仰賴其 URL 的隱私權,其中包含允許叫用 Webhook 的安全性權杖。 只要對正確的 URL 進行驗證,Azure 自動化就不會對要求執行任何驗證。 基於此原因,若不使用驗證要求的替代方式時,您的用戶端不應使用執行高度敏感性作業的 Webhook。

請考慮下列策略:

  • 您可以在 Runbook 中包含邏輯,以判斷它是否由 Webhook 呼叫。 讓 Runbook 檢查 WebhookName 參數的 WebhookData 屬性。 Runbook 可以藉由尋找 和 RequestBody 屬性中的 RequestHeader 特定資訊來執行進一步驗證。

  • 當 Runbook 收到 Webhook 要求時,請讓 Runbook 執行外部條件的一些驗證。 例如,請考慮每當 GitHub 有新認可至 GitHub 存放庫時所呼叫的 Runbook。 Runbook 可能會連線到 GitHub,以驗證是否已發生新的認可,然後再繼續。

  • Azure 自動化支援 Azure 虛擬網路服務標籤,特別是 GuestAndHybridManagement 。 您可以使用服務標籤來定義網路安全性群組的網路存取控制 ,或 Azure 防火牆 並從虛擬網路內觸發 Webhook。 建立安全性規則時,可以使用服務標籤取代特定的 IP 位址。 在規則的適當來源或目的地欄位中指定服務標籤名稱 GuestAndHybridManagement,即可允許或拒絕自動化服務的流量。 此服務標籤未支援藉由將 IP 範圍限制為特定區域來允許更細微的控制。

建立 Webhook

注意

當您搭配 PowerShell 7 Runbook 使用 Webhook 時,它會將 Webhook 輸入參數自動轉換成不正確 JSON。 如需詳細資訊,請參閱 已知問題 - PowerShell 7.1 (預覽版) 。 建議您搭配 PowerShell 5 Runbook 使用 Webhook。

  1. 使用下列程式碼建立 PowerShell Runbook:

    param
    (
        [Parameter(Mandatory=$false)]
        [object] $WebhookData
    )
    
    write-output "start"
    write-output ("object type: {0}" -f $WebhookData.gettype())
    write-output $WebhookData
    write-output "`n`n"
    write-output $WebhookData.WebhookName
    write-output $WebhookData.RequestBody
    write-output $WebhookData.RequestHeader
    write-output "end"
    
    if ($WebhookData.RequestBody) { 
        $names = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
    
            foreach ($x in $names)
            {
                $name = $x.Name
                Write-Output "Hello $name"
            }
    }
    else {
        Write-Output "Hello World!"
    }
    
  2. 使用 Azure 入口網站 或 PowerShell 或 REST API 建立 Webhook。 Webhook 需要已發佈的 Runbook。 本逐步解說會使用從 建立 Azure 自動化 Runbook 所建立的已修改 Runbook 版本。

    1. 登入 Azure 入口網站

    2. 在Azure 入口網站中,流覽至您的自動化帳戶。

    3. 在 [程式自動化] 底 下,選取 [Runbook] 以開啟 [Runbook] 頁面。

    4. 從清單中選取您的 Runbook,以開啟 [Runbook 概觀 ] 頁面。

    5. 選取 [新增 Webhook ] 以開啟 [ 新增 Webhook ] 頁面。

      Runbook overview page with Add webhook highlighted.

    6. 在 [ 新增 Webhook ] 頁面上,選取 [ 建立新的 Webhook ]。

      Add webhook page with create highlighted.

    7. 在 Webhook 的 [ 名稱 ] 中輸入 。 欄位 的到期 日預設為目前日期的一年。

    8. 按一下複製圖示,或按 Ctrl + C 複製 Webhook 的 URL。 然後將 URL 儲存到安全的位置。

      Creaye webhook page with URL highlighted.

      重要

      建立 Webhook 之後,就無法再次擷取 URL。 請務必複製並記錄為上述內容。

    9. 選取 [ 確定 ] 返回 [ 新增 Webhook ] 頁面。

    10. 從 [ 新增 Webhook ] 頁面中,選取 [ 設定參數],然後執行設定 以開啟 [ 參數 ] 頁面。

      Add webhook page with parameters highlighted.

    11. 檢閱 [ 參數] 頁面。 針對本文中使用的範例 Runbook,不需要變更。 選取 [ 確定 ] 返回 [ 新增 Webhook ] 頁面。

    12. 從 [ 新增 Webhook ] 頁面,選取 [ 建立 ]。 Webhook 隨即建立,並返回 Runbook [概觀 ] 頁面。


使用 Webhook

此範例會使用 PowerShell Cmdlet Invoke-WebRequest 將 POST 要求傳送至新的 Webhook。

  1. 準備值以傳遞至 Runbook 做為 Webhook 呼叫的主體。 對於相對簡單的值,您可以編寫值腳本,如下所示:

    $Names  = @(
                @{ Name="Hawaii"},
                @{ Name="Seattle"},
                @{ Name="Florida"}
            )
    
    $body = ConvertTo-Json -InputObject $Names
    
  2. 針對較大的集合,您可能想要使用檔案。 建立名為 names.json 的檔案,然後貼上下列程式碼:

    [
        { "Name": "Hawaii" },
        { "Name": "Florida" },
        { "Name": "Seattle" }
    ]
    

    在執行下列 PowerShell 命令之前,請先使用 json 檔案的實際路徑變更變數 $file 的值。

    # Revise file path with actual path
    $file = "path\names.json"
    $bodyFile = Get-Content -Path $file 
    
  3. 執行下列 PowerShell 命令,以使用 REST API 呼叫 Webhook。

    $response = Invoke-WebRequest -Method Post -Uri $webhookURI -Body $body -UseBasicParsing
    $response
    
    $responseFile = Invoke-WebRequest -Method Post -Uri $webhookURI -Body $bodyFile -UseBasicParsing
    $responseFile
    

    為了說明目的,已針對產生本文的兩種不同的方法發出兩個呼叫。 針對生產環境,請只使用一種方法。 輸出看起來應該如下所示(只會顯示一個輸出):

    Output from webhook call.

    用戶端會從 POST 要求接收下列其中一個傳回碼。

    代碼 Text 描述
    202 已接受 已接受要求,且 Runbook 已經成功排入佇列。
    400 不正確的要求 因為下列其中一個原因而不接受要求:
    • Webhook 已過期。
    • Webhook 已停用。
    • URL 中的權杖無效。
    404 找不到 因為下列其中一個原因而不接受要求:
    • 找不到 Webhook。
    • 找不到 Runbook。
    • 找不到帳戶。
    500 內部伺服器錯誤 URL 有效,但發生錯誤。 重新提交要求。

    假設要求成功,Webhook 回應會包含 JSON 格式的作業識別碼,如下所示。 它包含單一作業識別碼,但 JSON 格式允許潛在的未來增強功能。

    {"JobIds":["<JobId>"]}
    
  4. PowerShell Cmdlet Get-AzAutomationJobOutput 將用來取得輸出。 也可以使用Azure 自動化 API

    #isolate job ID
    $jobid = (ConvertFrom-Json ($response.Content)).jobids[0]
    
    # Get output
    Get-AzAutomationJobOutput `
        -AutomationAccountName $automationAccount `
        -Id $jobid `
        -ResourceGroupName $resourceGroup `
        -Stream Output
    

    當您觸發在上一個步驟中建立的 Runbook 時,它會建立作業,而輸出看起來應該類似下列:

    Output from webhook job.

更新 Webhook

建立 Webhook 時,其有效時間週期為 10 年,之後就會自動到期。 Webhook 過期之後,就無法重新啟用它。 您只能移除再重新建立它。 您可以將尚未達到到期時間的 Webhook 延長。 若要擴充 Webhook,請執行下列步驟。

  1. 請瀏覽至包含 Webhook 的 Runbook。
  2. 在 [資源] ,選取 [Webhook] ,然後選取 您想要擴充的 Webhook。
  3. 從 [Webhook ] 頁面中,選擇新的到期日期和時間,然後選取 [ 儲存 ]。

檢閱 API 呼叫 Webhook - Update 和 PowerShell Cmdlet Set-AzAutomationWebhook ,以取得其他可能的修改。

清除資源

以下是從自動化 Runbook 移除 Webhook 的範例。

  • 使用 PowerShell 時, 可以使用 Remove-AzAutomationWebhook Cmdlet,如下所示。 不會傳回任何輸出。

    Remove-AzAutomationWebhook `
        -ResourceGroup $resourceGroup `
        -AutomationAccountName $automationAccount `
        -Name $psWebhook
    
  • 使用 REST 時,可以使用 REST Webhook - 刪除 API,如下所示。

    Invoke-WebRequest -Method Delete -Uri $restURI -Headers $authHeader
    

    StatusCode : 200 輸出表示成功刪除。

使用 ARM 範本建立 Runbook 和 Webhook

您也可以使用 Azure Resource Manager 範本來建立自動化 Webhook。 此範例範本會為具名 Runbook 建立自動化帳戶、四個 Runbook 和 Webhook。

  1. 建立名為 webhook_deploy.json 的檔案,然後貼上下列程式碼:

    {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "automationAccountName": {
                "type": "String",
                "metadata": {
                    "description": "Automation account name"
                }
            },
            "webhookName": {
                "type": "String",
                "metadata": {
                    "description": "Webhook Name"
                }
            },
            "runbookName": {
                "type": "String",
                "metadata": {
                    "description": "Runbook Name for which webhook will be created"
                }
            },
            "WebhookExpiryTime": {
                "type": "String",
                "metadata": {
                    "description": "Webhook Expiry time"
                }
            },
            "_artifactsLocation": {
                "defaultValue": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.automation/101-automation/",
                "type": "String",
                "metadata": {
                    "description": "URI to artifacts location"
                }
            }
        },
        "resources": [
            {
                "type": "Microsoft.Automation/automationAccounts",
                "apiVersion": "2020-01-13-preview",
                "name": "[parameters('automationAccountName')]",
                "location": "[resourceGroup().location]",
                "properties": {
                    "sku": {
                        "name": "Free"
                    }
                },
                "resources": [
                    {
                        "type": "runbooks",
                        "apiVersion": "2018-06-30",
                        "name": "[parameters('runbookName')]",
                        "location": "[resourceGroup().location]",
                        "dependsOn": [
                            "[parameters('automationAccountName')]"
                        ],
                        "properties": {
                            "runbookType": "Python2",
                            "logProgress": "false",
                            "logVerbose": "false",
                            "description": "Sample Runbook",
                            "publishContentLink": {
                                "uri": "[uri(parameters('_artifactsLocation'), 'scripts/AzureAutomationTutorialPython2.py')]",
                                "version": "1.0.0.0"
                            }
                        }
                    },
                    {
                        "type": "webhooks",
                        "apiVersion": "2018-06-30",
                        "name": "[parameters('webhookName')]",
                        "dependsOn": [
                            "[parameters('automationAccountName')]",
                            "[parameters('runbookName')]"
                        ],
                        "properties": {
                            "isEnabled": true,
                            "expiryTime": "[parameters('WebhookExpiryTime')]",
                            "runbook": {
                                "name": "[parameters('runbookName')]"
                            }
                        }
                    }
                ]
            }
        ],
        "outputs": {
            "webhookUri": {
                "type": "String",
                "value": "[reference(parameters('webhookName')).uri]"
            }
        }
    }
    
  2. 下列 PowerShell 程式碼範例會從您的電腦部署範本。 為變數提供適當的值,然後執行腳本。

    $resourceGroup = "resourceGroup"
    $templateFile = "path\webhook_deploy.json"
    $armAutomationAccount = "automationAccount"
    $armRunbook = "ARMrunbookName"
    $armWebhook = "webhookName"
    $webhookExpiryTime = "12-31-2022"
    
    New-AzResourceGroupDeployment `
        -Name "testDeployment" `
        -ResourceGroupName $resourceGroup `
        -TemplateFile $templateFile `
        -automationAccountName $armAutomationAccount `
        -runbookName $armRunbook `
        -webhookName $armWebhook `
        -WebhookExpiryTime $webhookExpiryTime
    

    注意

    基於安全性考慮,URI 只會在第一次部署範本時傳回。

下一步