使用 webhook 启动 Azure 自动化 runbookStarting an Azure Automation runbook with a webhook

外部服务可以使用 Webhook 在 Azure 自动化中通过单个 HTTP 请求启动特定的 Runbook。A webhook allows an external service to start a particular runbook in Azure Automation through a single HTTP request. 外部服务包括 Azure DevOps Services、GitHub、Azure Monitor 日志和自定义应用程序。External services include Azure DevOps Services, GitHub, Azure Monitor logs, and custom applications. 此类服务可以使用 Webhook 来启动 Runbook,而无需使用 Azure 自动化 API 实施整个解决方案。Such a service can use a webhook to start a runbook without implementing a full solution using the Azure Automation API. 可将 Webhook 与在 Azure 自动化中启动 Runbook 中所述的其他 Runbook 启动方法进行比较。You can compare webhooks to other methods of starting a runbook in Starting a runbook in Azure Automation.

Note

不支持使用 Webhook 启动 Python runbook。Using a webhook to start a Python runbook is not supported.

WebhooksOverview

Webhook 属性Webhook properties

下表介绍了你必须为 Webhook 配置的属性。The following table describes the properties that you must configure for a webhook.

属性Property 说明Description
名称Name Webhook 的名称。Name of the webhook. 可以提供所需的任何名称,因为该名称不会向客户端公开。You can provide any name you want, since it isn't exposed to the client. 它只用来标识 Azure 自动化中的 Runbook。It's only used for you to identify the runbook in Azure Automation. 最好是为 Webhook 提供一个名称,该名称需要与使用它的客户端相关。As a best practice, you should give the webhook a name related to the client that uses it.
URLURL Webhook 的 URL。URL of the webhook. 此 URL 是客户端通过 HTTP POST 调用的、用于启动链接到 Webhook 的 Runbook 的唯一地址。This is the unique address that a client calls with an HTTP POST to start the runbook linked to the webhook. 它是在创建 Webhook 时自动生成的。It's automatically generated when you create the webhook. 无法指定自定义 URL。You can't specify a custom URL.

该 URL 包含一个安全令牌,第三方系统可以使用该令牌调用 Runbook,而无需进一步执行身份验证。The URL contains a security token that allows a third-party system to invoke the runbook with no further authentication. 因此,应将该 URL 视为密码。For this reason, you should treat the URL like a password. 出于安全原因,只能在创建 Webhook 时通过 Azure 门户查看该 URL。For security reasons, you can only view the URL in the Azure portal when creating the webhook. 请将保存在安全位置的 URL 记下来,供将来使用。Note the URL in a secure location for future use.
到期日期Expiration date Webhook 的过期日期,此日期过后,该 Webhook 不再可用。Expiration date of the webhook, after which it can no longer be used. 创建 Webhook 后,只要它没有过期,就可以修改过期日期。You can modify the expiration date after the webhook is created, as long as the webhook has not expired.
EnabledEnabled 该设置指示在创建 Webhook 时是否默认启用它。Setting indicating if the webhook is enabled by default when it's created. 如果将此属性设置为“已禁用”,则任何客户端都不可以使用该 Webhook。If you set this property to Disabled, no client can use the webhook. 可以在创建 Webhook 时设置此属性,也可以在创建后随时设置它。You can set this property when you create the webhook or any other time after its creation.

Webhook 启动 Runbook 时使用的参数Parameters used when the webhook starts a runbook

Webhook 可以定义 Runbook 参数的值,启动 Runbook 时会使用这些值。A webhook can define values for runbook parameters that are used when the runbook starts. Webhook 必须包含所有 Runbook 必需参数的值,可以包含可选参数的值。The webhook must include values for any mandatory runbook parameters and can include values for optional parameters. 即使在创建 Webhook 后,也可以修改配置给 Webhook 的参数值。A parameter value configured to a webhook can be modified even after webhook creation. 链接到单个 Runbook 的多个 Webhook 可以使用不同的 Runbook 参数值。Multiple webhooks linked to a single runbook can each use different runbook parameter values. 客户端在使用 Webhook 启动 Runbook 时,无法重写在 Webhook 中定义的参数值。When a client starts a runbook using a webhook, it can't override the parameter values defined in the webhook.

若要从客户端接收数据,Runbook 支持名为 WebhookData 的单个参数。To receive data from the client, the runbook supports a single parameter called WebhookData. 此参数定义一个对象,该对象包含客户端在 POST 请求中加入的数据。This parameter defines an object containing data that the client includes in a POST request.

WebhookData 属性

WebhookData 参数具有以下属性:The WebhookData parameter has the following properties:

属性Property 说明Description
WebhookName Webhook 的名称。Name of the webhook.
RequestHeader 包含传入 POST 请求标头的哈希表。Hashtable containing the headers of the incoming POST request.
RequestBody 传入 POST 请求的正文。Body of the incoming POST request. 此正文保留任何数据格式,例如字符串、JSON、XML,或表单编码格式。This body retains any data formatting, such as string, JSON, XML, or form-encoded. 编写的 Runbook 必须能够与预期的数据格式配合工作。The runbook must be written to work with the data format that is expected.

无需配置 Webhook 即可支持 WebhookData 参数,且不需要 Runbook 接受此参数。There's no configuration of the webhook required to support the WebhookData parameter, and the runbook isn't required to accept it. 如果 Runbook 未定义该参数,则会忽略从客户端发送的请求的任何详细信息。If the runbook doesn't define the parameter, any details of the request sent from the client are ignored.

Note

调用 Webhook 时,客户端应始终存储任何参数值,以防调用失败。When calling a webhook, the client should always store any parameter values in case the call fails. 如果出现网络中断或连接问题,应用程序将无法检索失败的 Webhook 调用。If there is a network outage or connection issue, the application can't retrieve failed webhook calls.

如果在创建 Webhook 时为 WebhookData 指定了值,则会在 Webhook 使用客户端 POST 请求中的数据启动 Runbook 时重写该值。If you specify a value for WebhookData at webhook creation, it is overridden when the webhook starts the runbook with the data from the client POST request. 即使应用程序未在请求正文中包含任何数据,也会发生这种情况。This happens even if the application does not include any data in the request body.

如果使用除 Webhook 以外的机制启动定义了 WebhookData 的 Runbook,则可为能够被 Runbook 识别的 WebhookData 提供值。If you start a runbook that defines WebhookData using a mechanism other than a webhook, you can provide a value for WebhookData that the runbook recognizes. 此值应是与 WebhookData 参数具有相同属性的对象,这样,Runbook 就可以正常使用此值,如同使用 Webhook 传递的实际 WebhookData 对象时一样。This value should be an object with the same properties as the WebhookData parameter so that the runbook can work with it just as it works with actual WebhookData objects passed by a webhook.

例如,如果你从 Azure 门户启动以下 Runbook,并想要传递一些示例 Webhook 数据进行测试,则必须在用户界面中传递 JSON 格式的数据。For example, if you are starting the following runbook from the Azure portal and want to pass some sample webhook data for testing, you must pass the data in JSON in the user interface.

UI 中的 WebhookData 参数

对于下一个 Runbook 示例,让我们为 WebhookData 定义以下属性:For the next runbook example, let's define the following properties for WebhookData:

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

现在,我们在 UI 中为 WebhookData 参数传递以下 JSON 对象。Now we pass the following JSON object in the UI for the WebhookData parameter. 以下示例使用了回车符和换行符,这与从 Webhook 传入的格式相匹配。This example, with carriage returns and newline characters, matches the format that is passed in from a 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]"}

UI 中的启动 WebhookData 参数

Note

Azure 自动化将记录 Runbook 作业的所有输入参数的值。Azure Automation logs the values of all input parameters with the runbook job. 因此,客户端在 Webhook 请求中提供的任何输入都会记录下来,并可供有权访问自动化作业的任何人使用。Thus any input provided by the client in the webhook request is logged and available to anyone with access to the automation job. 因此,在 Webhook 调用中包括敏感信息时,应该特别小心。For this reason, you should be cautious about including sensitive information in webhook calls.

Webhook 安全性Webhook security

Webhook 的安全性取决于其 URL 的私密性。URL 中包含一个用于调用该 Webhook 的安全令牌。The security of a webhook relies on the privacy of its URL, which contains a security token that allows the webhook to be invoked. 如果请求是向正确的 URL 发出的,Azure 自动化不对请求执行任何身份验证。Azure Automation does not perform any authentication on a request as long as it is made to the correct URL. 因此,对于在不使用替代方式验证请求的情况下执行高敏感性操作的 Runbook,客户端不应使用 Webhook。For this reason, your clients should not use webhooks for runbooks that perform highly sensitive operations without using an alternate means of validating the request.

可以将逻辑包括在 Runbook 中,以确定它是否由 Webhook 调用。You can include logic within a runbook to determine if it is called by a webhook. 让 Runbook 检查 WebhookData 参数的 WebhookName 属性。Have the runbook check the WebhookName property of the WebhookData parameter. 该 Runbook 可以通过在 RequestHeaderRequestBody 属性中查找特定的信息来执行进一步的验证。The runbook can perform further validation by looking for particular information in the RequestHeader and RequestBody properties.

另一种策略是让 Runbook 在收到 Webhook 请求时对外部条件执行某种验证。Another strategy is to have the runbook perform some validation of an external condition when it receives a webhook request. 例如,假设每当有新的内容提交到 GitHub 存储库时,GitHub 将调用某个 Runbook。For example, consider a runbook that is called by GitHub any time there's a new commit to a GitHub repository. 该 Runbook 在继续之前,可以连接到 GitHub 来验证是否有新的提交内容。The runbook might connect to GitHub to validate that a new commit has occurred before continuing.

创建 WebhookCreate a webhook

在 Azure 门户中使用以下过程来创建新的链接到 Runbook 的 Webhook。Use the following procedure to create a new webhook linked to a runbook in the Azure portal.

  1. 在 Azure 门户上的“Runbook”页中,单击 Webhook 要启动的 Runbook 以查看其详细信息。From the Runbooks page in the Azure portal, click the runbook that the webhook starts to view the runbook details. 确保 Runbook 的“状态”字段设置为“已发布”。 Ensure that the runbook Status field is set to Published.

  2. 单击页面顶部的“Webhook”打开“添加 Webhook”页。Click Webhook at the top of the page to open the Add Webhook page.

  3. 单击“创建新的 Webhook”打开“创建 Webhook”页。Click Create new webhook to open the Create Webhook page.

  4. 填写 Webhook 的“名称”和“过期日期”字段,并指定是否要启用它。 Fill in the Name and Expiration Date fields for the webhook and specify if it should be enabled. 有关这些属性的详细信息,请参阅 Webhook 属性See Webhook properties for more information about these properties.

  5. 单击复制图标,并按 Ctrl+C 以复制 Webhook 的 URL。Click the copy icon and press Ctrl+C to copy the URL of the webhook. 然后,将其记录在某个安全的位置。Then record it in a safe place.

    Note

    一旦创建 Webhook,就再也不能检索该 URL。Once you create the webhook, you cannot retrieve the URL again.

    Webhook URL

  6. 单击“参数” 为 Runbook 参数提供值。Click Parameters to provide values for the runbook parameters. 如果 Runbook 包含必需的参数,除非提供了值,否则无法创建 Webhook。If the runbook has mandatory parameters, you can't create the webhook unless you provide values.

  7. 单击“创建”以创建 Webhook 。Click Create to create the webhook.

使用 WebhookUse a webhook

若要在创建 Webhook 后使用该 Webhook,客户端必须发出包含 Webhook URL 的 HTTP POST 请求。To use a webhook after it has been created, your client must issue an HTTP POST request with the URL for the webhook. 语法为:The syntax is:

http://<Webhook Server>/token?=<Token Value>

客户端从 POST 请求中接收以下返回代码之一。The client receives one of the following return codes from the POST request.

代码Code 文本Text 说明Description
202202 已接受Accepted 已接受该请求,并已成功将 Runbook 排队。The request was accepted, and the runbook was successfully queued.
400400 错误的请求Bad Request 出于以下原因之一,未接受该请求:The request was not accepted for one of the following reasons:
  • Webhook 已过期。The webhook has expired.
  • Webhook 已禁用。The webhook is disabled.
  • URL 中的令牌无效。The token in the URL is invalid.
404404 未找到Not Found 出于以下原因之一,未接受该请求:The request was not accepted for one of the following reasons:
  • 找不到 Webhook。The webhook was not found.
  • 找不到 Runbook。The runbook was not found.
  • 找不到帐户。The account was not found.
500500 内部服务器错误Internal Server Error URL 有效,但出现了错误。The URL was valid, but an error occurred. 请重新提交请求。Please resubmit the request.

假设请求成功,Webhook 响应将包含 JSON 格式的作业 ID,如下所示。Assuming the request is successful, the webhook response contains the job ID in JSON format as shown below. 响应包含单个作业 ID,但 JSON 格式支持将来可能的增强功能。It contains a single job ID, but the JSON format allows for potential future enhancements.

{"JobIds":["<JobId>"]}

客户端无法从 Webhook 确定 Runbook 的作业何时完成或其完成状态。The client can't determine when the runbook job completes or its completion status from the webhook. 可以使用作业 ID 并配合其他机制(例如 Windows PowerShellAzure 自动化 API)找到此信息。It can find out this information using the job ID with another mechanism, such as Windows PowerShell or the Azure Automation API.

续订 WebhookRenew a webhook

创建 Webhook 后,其有效期为十年,此期限过后,它会自动过期。When a webhook is created, it has a validity time period of ten years, after which it automatically expires. Webhook 过期后,无法重新激活它。Once a webhook has expired, you can't reactivate it. 只能删除然后重新创建它。You can only remove and then recreate it.

对于尚未过期的 Webhook,可将其延期。You can extend a webhook that has not reached its expiration time. 若要将 Webhook 延期:To extend a webhook:

  1. 导航到包含该 Webhook 的 Runbook。Navigate to the runbook that contains the webhook.
  2. 选择“资源”****下的“Webhook”****。Select Webhooks under Resources.
  3. 单击要延期的 Webhook。Click the webhook that you want to extend.
  4. 在“Webhook”页中,选择新的过期日期和时间,然后单击“保存”。In the Webhook page, choose a new expiration date and time and click Save.

示例 RunbookSample runbook

以下示例 Runbook 将接受 Webhook 数据,并启动请求正文中指定的虚拟机。The following sample runbook accepts the webhook data and starts the virtual machines specified in the request body. 若要测试此 Runbook,请在自动化帐户中的“Runbook”下,单击“创建 Runbook”。 To test this runbook, in your Automation account under Runbooks, click Create a runbook. 如果不知道如何创建 Runbook,请参阅创建 RunbookIf you don't know how to create a runbook, see Creating a runbook.

param
(
    [Parameter (Mandatory = $false)]
    [object] $WebhookData
)

# If runbook was called from Webhook, WebhookData will not be null.
if ($WebhookData) {

    # Check header for message to validate request
    if ($WebhookData.RequestHeader.message -eq 'StartedbyContoso')
    {
        Write-Output "Header has required information"}
    else
    {
        Write-Output "Header missing required information";
        exit;
    }

    # Retrieve VMs from Webhook request body
    $vms = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)

    # Authenticate to Azure by using the service principal and certificate. Then, set the subscription.

    Write-Output "Authenticating to Azure with service principal and certificate"
    $ConnectionAssetName = "AzureRunAsConnection"
    Write-Output "Get connection asset: $ConnectionAssetName"

    $Conn = Get-AutomationConnection -Name $ConnectionAssetName
            if ($Conn -eq $null)
            {
                throw "Could not retrieve connection asset: $ConnectionAssetName. Check that this asset exists in the Automation account."
            }
            Write-Output "Authenticating to Azure with service principal."
            Add-AzureRmAccount -EnvironmentName AzureChinaCloud -ServicePrincipal -Tenant $Conn.TenantID -ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint | Write-Output

        # Start each virtual machine
        foreach ($vm in $vms)
        {
            $vmName = $vm.Name
            Write-Output "Starting $vmName"
            Start-AzureRMVM -Name $vm.Name -ResourceGroup $vm.ResourceGroup
        }
}
else {
    # Error
    write-Error "This runbook is meant to be started from an Azure alert webhook only."
}

测试示例Test the sample

以下示例使用 Windows PowerShell 并配合 Webhook 来启动 Runbook。The following example uses Windows PowerShell to start a runbook with a webhook. 任何可以发出 HTTP 请求的语言都可以使用 Webhook。Any language that can make an HTTP request can use a webhook. 此处使用 Windows PowerShell 作为示例。Windows PowerShell is used here as an example.

Runbook 预期请求的正文中包含 JSON 格式的虚拟机列表。The runbook is expecting a list of virtual machines formatted in JSON in the body of the request. Runbook 还将验证标头是否包含用于验证 Webhook 调用方是否有效的已定义消息。The runbook validates as well that the headers contain a defined message to validate that the webhook caller is valid.

$uri = "<webHook Uri>"

$vms  = @(
            @{ Name="vm01";ResourceGroup="vm01"},
            @{ Name="vm02";ResourceGroup="vm02"}
        )
$body = ConvertTo-Json -InputObject $vms
$header = @{ message="StartedbyContoso"}
$response = Invoke-WebRequest -Method Post -Uri $uri -Body $body -Headers $header
$jobid = (ConvertFrom-Json ($response.Content)).jobids[0]

以下示例显示了请求的正文,此正文可在 WebhookDataRequestBody 属性中提供给 Runbook 使用。The following example shows the body of the request that is available to the runbook in the RequestBody property of WebhookData. 此值采用 JSON 格式,以便与请求正文中包含的格式兼容。This value is formatted in JSON to be compatible with the format included in the body of the request.

[
    {
        "Name":  "vm01",
        "ResourceGroup":  "myResourceGroup"
    },
    {
        "Name":  "vm02",
        "ResourceGroup":  "myResourceGroup"
    }
]

下图显示了从 Windows PowerShell 发送的请求以及生成的响应。The following image shows the request being sent from Windows PowerShell and the resulting response. 作业 ID 是从响应中提取的,并转换为字符串。The job ID is extracted from the response and converted to a string.

Webhook 按钮

后续步骤Next steps