Inicio de un runbook desde un webhook

Un webhook permite que un servicio externo inicie un runbook determinado en Azure Automation mediante una sola solicitud HTTP. Entre los servicios externos se incluyen Azure DevOps Services, GitHub, registros de Azure Monitor y aplicaciones personalizadas. Estos servicios pueden usar un webhook para iniciar un runbook sin tener que implementar la API completa de Azure Automation. Puede comparar los webhooks con otros métodos para iniciar un runbook en Inicio de un runbook en Azure Automation.

Información general sobre webhooks

Para comprender los requisitos de cliente para TLS 1.2 o superior con webhooks, consulte TLS para Azure Automation.

Propiedades de un webhook

En la tabla siguiente se describen las propiedades que debe configurar para un webhook.

Propiedad Descripción
Nombre Nombre del webhook. Puede indicar cualquier nombre que desee, ya que no se expone al cliente. Solo se utiliza para que identifique el runbook en Azure Automation. Como práctica recomendada, debe proporcionar al webhook un nombre relacionado con el cliente que lo usa.
URL Dirección URL del webhook. Es la dirección única a la que llama un cliente con una solicitud HTTP POST para iniciar el runbook vinculado al webhook. Se genera automáticamente al crear el webhook. No se puede especificar una dirección URL personalizada.

La dirección URL contiene un token de seguridad que permite que un sistema de terceros invoque el runbook sin autenticación adicional, por lo que debe tratarla como una contraseña. Por motivos de seguridad, solo puede ver la dirección URL en Azure Portal cuando se crea el webhook. Anote la dirección URL en una ubicación segura para su uso futuro.
Fecha de expiración Fecha de expiración del webhook, tras la cual ya no se puede usar. Esta fecha se puede modificar una vez creado el webhook, siempre y cuando no haya expirado.
Habilitado Este valor indica si el webhook se habilita de forma predeterminada cuando se crea. Si establece esta propiedad en Deshabilitado, ningún cliente puede usar el webhook. Puede establecer esta propiedad al crear el webhook o en cualquier otro momento después de su creación.

Parámetros usados cuando el webhook inicia un runbook

Un webhook puede definir valores para parámetros de runbook que se usan cuando se inicia el runbook. El webhook debe incluir los valores de los parámetros obligatorios del runbook y puede incluir valores para los parámetros opcionales. Los valores de parámetro configurados en un webhook se pueden modificar incluso después de crear el webhook. Varios webhooks vinculados a un único runbook puede utilizar distintos valores de parámetros de runbook. Cuando un cliente inicia un runbook mediante un webhook, no puede reemplazar los valores de los parámetros definidos en el webhook.

Para recibir datos del cliente, el runbook admite un único parámetro llamado WebhookData. Este parámetro define un objeto que contiene datos que el cliente incluye en una solicitud POST.

Propiedades de WebhookData

El parámetro WebhookData tiene las siguientes propiedades:

Propiedad Descripción
WebhookName Nombre del webhook.
RequestHeader PSCustomObject que contiene los encabezados de la solicitud POST entrante.
RequestBody Cuerpo de la solicitud POST entrante. Este cuerpo conserva el formato de los datos, como cadena, JSON, XML o datos codificados por formulario. El runbook debe escribirse para que trabaje con el formato de datos que se espera.

No hay ninguna configuración del webhook obligatoria para admitir el parámetro WebhookData, y el runbook no tiene que aceptarlo. Si el runbook no define el parámetro, se ignoran los detalles de la solicitud enviada desde el cliente.

Nota:

Al llamar a un webhook, el cliente siempre debe almacenar los valores de los parámetros, por si se produce un error en la llamada. Si se produce un problema de conexión o de interrupción de la red, la aplicación no podrá recuperar las llamadas de webhook con errores.

Si especifica un valor para WebhookData durante la creación del webhook, se invalidará cuando el webhook inicie el runbook con los datos de la solicitud POST del cliente. Esto sucederá incluso si la aplicación no contiene ningún dato en el cuerpo de la solicitud.

Si inicia un runbook que define WebhookData mediante un mecanismo que no sea un webhook, puede proporcionar un valor para WebhookData que el runbook reconozca. Este valor debe ser un objeto con las mismas propiedades que el parámetro WebhookData, para que el runbook pueda funcionar correctamente con él, del mismo modo que si trabajara con objetos WebhookData reales pasados por un webhook.

Por ejemplo, si va a iniciar el siguiente runbook desde Azure Portal y desea pasar algunos datos de webhook de ejemplo para las pruebas, debe pasarlos como JSON en la interfaz de usuario.

Parámetro WebhookData de la interfaz de usuario

En el siguiente ejemplo de runbook, vamos a definir las siguientes propiedades para WebhookData:

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

Ahora pasamos el siguiente objeto JSON en la interfaz de usuario para el parámetro WebhookData. Este ejemplo, con los retornos de carro y los caracteres de nueva línea, coincide con el formato que se pasa desde un 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]"}

Iniciar el parámetro WebhookData de la interfaz de usuario

Nota:

Azure Automation registra los valores de todos los parámetros de entrada con el trabajo de runbook. Por tanto, se registra cualquier entrada que proporcione el cliente en la solicitud de webhook, y esta entrada estará disponible para cualquiera con acceso al trabajo de automatización. Por este motivo, debe tener cuidado en cómo incluir información confidencial en las llamadas de webhook.

Seguridad del webhook

La seguridad de un webhook se basa en la privacidad de su dirección URL, que contiene un token de seguridad que permite que se invoque el webhook. Azure Automation no realiza ninguna autenticación en una solicitud, siempre que se haga en la dirección URL correcta. Por esta razón, los clientes no deben utilizar webhooks en runbooks que realicen operaciones altamente confidenciales sin utilizar medios alternativos para validar la solicitud.

Considere las estrategias siguientes:

  • Puede incluir lógica dentro de un runbook para determinar si se le llama desde un webhook. Establezca que el runbook compruebe la propiedad WebhookName del parámetro WebhookData. El runbook puede realizar más validaciones buscando información determinada en las propiedades RequestHeader y RequestBody.

  • Haga que el runbook realice alguna validación de una condición externa cuando recibe una solicitud de webhook. Por ejemplo, considere un runbook al que llama GitHub siempre que hay una nueva confirmación en un repositorio de GitHub. El runbook puede conectarse a GitHub para asegurarse de que se ha realizado una nueva confirmación antes de continuar.

  • Azure Automation admite etiquetas de servicio de red virtual de Azure, específicamente GuestAndHybridManagement. Puede usar etiquetas de servicio para definir controles de acceso a la red en grupos de seguridad de red o Azure Firewall y desencadenar webhooks desde la red virtual. Las etiquetas de servicio se pueden usar en lugar de direcciones IP específicas al crear reglas de seguridad. Al especificar el nombre de la etiqueta de servicio GuestAndHybridManagement en el campo de origen o destino apropiado de una regla, puede permitir o denegar el tráfico para el servicio Automation. Esta etiqueta de servicio no admite un control más pormenorizado mediante la restricción de los intervalos de IP a una región específica.

Creación de un webhook

Nota:

Al iniciar el runbook de PowerShell 7 mediante el webhook, convierte automáticamente el parámetro de entrada del webhook en un JSON no válido. Para obtener más información, consulte Problemas conocidos - PowerShell7.1 (vista preliminar). Se recomienda usar el webhook con el runbook de PowerShell 5.

  1. Cree un runbook de PowerShell con el código siguiente:

    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. Cree un webhook mediante la Azure Portal, PowerShell o la API REST. Un webhook requiere un runbook publicado. En este recorrido se usa una versión modificada del runbook creada en Creación de un runbook de Azure Automation.

    1. Inicie sesión en Azure Portal.

    2. En Azure Portal, vaya a su cuenta de Automation.

    3. En Automatización de procesos, seleccione Runbooks para abrir la página de runbooks.

    4. Seleccione el runbook en la lista para abrir la página Información general del runbook.

    5. Seleccione Agregar Webhook para abrir la página Agregar Webhook.

      Página de información general del runbook con Agregar Webhook resaltado.

    6. En la página Agregar Webhook, seleccione Crear nuevo Webhook.

      Página Agregar Webhook con Crear resaltado.

    7. Escriba el Nombre del webhook. La fecha de expiración del campo Expira tiene como valor predeterminado un año a partir de la fecha actual.

    8. Haga clic en el icono de copia y presione Ctrl + C para copiar la dirección URL del webhook. A continuación, guarde la dirección URL en una ubicación segura.

      Página Crear webhook con la dirección URL resaltada.

      Importante

      Una vez creado el webhook, ya no puede volver a recuperar la dirección URL. Asegúrese de copiarlo y grabarlo como se indicó anteriormente.

    9. Seleccione Aceptar para volver a la página Agregar Webhook.

    10. En la página Agregar Webhook, seleccione Configurar parámetros y ejecutar configuraciones para abrir la página Parámetros.

      Página Agregar Webhook con los parámetros resaltados.

    11. Revise la página Parámetros. Para el runbook de ejemplo que se usa en este artículo, no se necesita ningún cambio. Seleccione Aceptar para volver a la página Agregar Webhook.

    12. En la página Agregar Webhook, seleccione Crear. Se crea el webhook y se le devuelve a la página Información general del runbook.


Uso de webhooks

En este ejemplo se usa el cmdlet de PowerShell Invoke-WebRequest para enviar una solicitud PUT al nuevo webhook.

  1. Prepare los valores para pasar al runbook como cuerpo de la llamada de webhook. En el caso de los valores relativamente simples, puede incluir los valores en un script, como se muestra a continuación:

    $Names  = @(
                @{ Name="Hawaii"},
                @{ Name="Seattle"},
                @{ Name="Florida"}
            )
    
    $body = ConvertTo-Json -InputObject $Names
    
  2. En el caso de conjuntos más grandes, puede ser aconsejable usar un archivo. Cree un archivo denominado names.json y pegue el código siguiente:

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

    Cambie el valor de la variable $file por la ruta de acceso real al archivo JSON antes de ejecutar los siguientes comandos de PowerShell.

    # Revise file path with actual path
    $file = "path\names.json"
    $bodyFile = Get-Content -Path $file 
    
  3. Ejecute los siguientes comandos de PowerShell para llamar al webhook mediante la API de REST.

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

    Con fines ilustrativos, se realizaron dos llamadas para los dos métodos diferentes de generar el cuerpo. Para producción, use solo un método. La salida debe tener un aspecto similar al siguiente (solo se muestra una salida):

    Salida de la llamada de webhook.

    El cliente recibe uno de los siguientes códigos de retorno de la solicitud POST.

    Código Texto Descripción
    202 Accepted La solicitud se aceptó y el runbook se puso en cola correctamente.
    400 Bad Request No se aceptó la solicitud por uno de los siguientes motivos:
    • El webhook ha expirado.
    • El webhook está deshabilitado.
    • El token de la dirección URL no es válido.
    404 No encontrado No se aceptó la solicitud por uno de los siguientes motivos:
    • No se encontró el webhook.
    • No se encontró el runbook.
    • No se encontró la cuenta.
    500 Internal Server Error La dirección URL es válida, pero se produjo un error. Vuelva a enviar la solicitud.

    Si la solicitud es correcta, la respuesta del webhook contiene el identificador de trabajo en formato JSON, como se muestra a continuación. Contiene un solo identificador de trabajo, pero el formato JSON permite realizar potenciales mejoras en el futuro.

    {"JobIds":["<JobId>"]}
    
  4. El cmdlet de PowerShell Get-AzAutomationJobOutput se usará para obtener la salida. También se puede usar la API de Azure Automation.

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

    Cuando se desencadena un runbook creado en el paso anterior, se crea un trabajo y la salida debe ser similar a la siguiente:

    Salida del trabajo de webhook.

Actualización de un webhook

Cuando se crea un webhook, tiene un período de validez de 10 años, tras el cual expira automáticamente. Una vez que un webhook ha expirado, no se puede reactivar. Solo se puede quitar y volver a crear. Puede extender un webhook que no haya alcanzado su fecha de expiración. Para extender un webhook, realice los pasos siguientes.

  1. Vaya al runbook que contiene el webhook.
  2. En Recursos, seleccione Webhooks y, a continuación, el webhook que quiera extender.
  3. En la página Webhook, elija una nueva fecha y hora de expiración y haga clic en Guardar.

Revise la llamada API Webhook: Actualización y el cmdlet de PowerShell Set-AzAutomationWebhook para ver otras modificaciones posibles.

Limpieza de recursos

Estos son ejemplos de cómo quitar un webhook de un runbook de Automation.

  • Con PowerShell, se puede usar el cmdlet Remove-AzAutomationWebhook como se muestra a continuación. No se devuelve salida.

    Remove-AzAutomationWebhook `
        -ResourceGroup $resourceGroup `
        -AutomationAccountName $automationAccount `
        -Name $psWebhook
    
  • Con REST, se puede usar la API de REST Webhook: Eliminación como se muestra a continuación.

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

    Una salida de StatusCode : 200 significa una eliminación correcta.

Creación de un runbook y un webhook con una plantilla de ARM

También se pueden crear los webhooks de Automation de forma automática por medio de las plantillas de Azure Resource Manager. Esta plantilla de ejemplo crea una cuenta de Automation, cuatro runbooks y un webhook para el runbook con nombre.

  1. Cree un archivo denominado webhook_deploy.json y pegue el código siguiente:

    {
        "$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. En el siguiente ejemplo de código de PowerShell se implementa la plantilla desde el equipo. Proporcione un valor adecuado para las variables y, después, ejecute el script.

    $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
    

    Nota:

    Por motivos de seguridad, el URI solo se devuelve la primera vez que se implementa una plantilla.

Pasos siguientes