← Back to overview
February 3, 2016 · Webtask Microsoft Azure Azure Automation

Create advanced webhooks for Azure Automation with a Webtask

Azure Automation already supports webhooks but these are currently scoped to a single runbook. This post explains how you can use a Webtask to send secret settings (encrypted), internal settings (which the caller of the webhook cannot change) and also public settings to your Runbook. These public settings allow you to:

The goal here is that we can create a webhook that would work like this:

https://webtask.it.auth0.com/api/run/YOUR_CONTAINER/my-webhook?RUNBOOK_NAME=Sample-Runbook&some_value=123  

This would then run Sample-Runbook with these parameters: some_value=123

Prerequisites

You'll need an Automation Account and a Runbook (make sure you also publish it!). Here's a sample Runbook you can use:

workflow Sample-Runbook  
{
   param ([Parameter(Mandatory=$false)][object]$context)
    # Context which was sent to the runbook.
    if ($context) {
        $body = ConvertTo-Json -InputObject $context 
        Write-Output "You sent: ${body}"
    } else {
        Write-Output "You did not send anything."
    }

    # Get the credential.
    $credentialName = 'DefaultAzureCredential'
    $credential = Get-AutomationPSCredential -Name $credentialName
    if(!$credential) {
        Throw "Could not find an Automation Credential Asset named '${credentialName}'. Make sure you have created one in this Automation Account."
    }

    # Connect to your Azure Account
    $account = Add-AzureAccount -Credential $credential
    if(!$account) {
        Throw "Could not authenticate to Azure using the credential asset '${credential}'. Make sure the user name and password are correct."
    }

    # Return Subscription
    $subscription = Get-AzureSubscription -Default
    $subscriptionBody = ConvertTo-Json -InputObject $subscription
    Write-Output "Your default Azure subscription is: ${subscriptionBody}"
}

Note that the $context parameter here is important, as the Webtask will send everything over in the context parameter (JSON object).

The Webtask

The full source of the Webtask is available on Github.

This Webtask will do a few things:

Here is the most important part of the code:

  const internalSettings = {
    resourceGroup: "lab",
    automationAccount: "automation-lab"
  };

  authenticate(ctx.data.AD_TENANT_ID, ctx.data.AD_CLIENT_ID, ctx.data.AD_SERVICE_PRINCIPAL_PASSWORD, (err, accessToken) => {
    if (err) {
      return done({
        message: 'Error authenticating.',
        err: err
      });
    }

    const jobId = uuid.v4();
    const parameters = _.extend({ }, ctx.query, { 
        someInternalValue: 1,
        someSecretValue: ctx.data.AD_CLIENT_ID
    });

    const req = {
      properties: {
        runbook: {
           name: ctx.query.RUNBOOK_NAME
        },
        parameters: {
           context: JSON.stringify(parameters),
           MicrosoftApplicationManagementStartedBy: "\"A Webtask\""
        }
      },
      tags: {}
    };

    const path = `/providers/Microsoft.Automation/automationAccounts/${internalSettings.automationAccount}/jobs/${jobId}?api-version=2015-01-01-preview`
    sendRequest(accessToken, ctx.data.AZURE_SUBSCRIPTION_ID, internalSettings.resourceGroup, path, req, (err, body) => {
      if (err) {
        console.log('Error starting Runbook:', err.message || JSON.stringify(err, null, 2));
        return done({ err: err });
      }

      console.log(`Success: ${JSON.stringify(body, null, 2)}`)
      return done(null, body);
    });
  });

As you can see, parameters which are sent to the Runbook are populated with:

And that's basically it.

Deployment

Download task.js from this repository and change it to match your needs:

Once your task is ready you can go ahead and deploy it (on Windows you might have to wrap the wt create command in a single line):

npm i -g wt-cli  
wt init  
wt create task.js \  
    --name some-random-name-that-is-hard-to-guess \
    --secret AD_TENANT_ID="YOUR_TENANT_ID" \
    --secret AD_CLIENT_ID="YOUR_CLIENT_ID" \
    --secret AD_SERVICE_PRINCIPAL_PASSWORD="SP_PASSWORD" \
    --secret AZURE_SUBSCRIPTION_ID="YOUR_SUBSCRIPTION_ID"

Note: This blog post explains how you can create a Service Principal and access these values.

Usage

After creating the Webtask the wt-cli will return the URL of my Webtask and I can just go ahead and hit it using Postman for example (notice the query string values and how they are passed along in the parameters.context:

Calling the Webtask from Postman

Head back to the Azure portal and you'll see the status of the job, the input values and the Runbook output:

Runbook Output

What's next?

Well... a Slack integration of course. Creating a Slash command is pretty easy, but let's see if we can do something that reports the status of the job (even for long running processes).

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket
Comments powered by Disqus