I’ve been studying a lot of cloud-based architecture lately, focused on the best ways to blend it with SD-WAN infrastructure. One of the most overlooked options involves how to receive up-to-date alerts from the vManage without having to sit and watch a dedicated dashboard.

Thankfully, vManage supports webhooks. Webhooks are the new darling of alerting, much faster than sending an email when things break, it can instead send an HTTP POST request to a remote server that can ingest the data and do just about anything with it. Imagine, instead of receiving an email when something breaks, a real-time system could get your attention using a push notification, such as Slack, Discord, or WebEx Teams? That frees up the team to leave the computers behind, as well saving them from trying to look at dashboards on their phones.

Webhooks themselves are hardly new at this point, nor is setting up a notification system. The solution I’ve been working on (and it’s not in any way revolutionary, others have done the same, maybe even better) is to transform this entire system into a serverless, free (within the limitations of AWS Free Tier) application that requires no infrastructure to maintain.

It consists of four total moving parts, which we’ll cover in turn. The easiest place to start is probably by creating the bot or code that will ultimately deliver the notification to your platform of choice. I’m using WebEx Teams for this use case, so I start there.


Create the Alert Bot

Create a WebEx Bot for Free! https://developer.webex.com/docs/bots

I’m covering the WebEx Bot use case because that’s what I used. Obviously if you choose to go with another platform, refer to those docs.


Provide the details here, and keep track of the name of your bot. You’ll use that later to add it to the Alert WebEx Teams Room.

Copy this token as it is an important piece of data we will use when we create the actual code to send messages to WebEx Teams later.

Let’s create the Webex Teams Alert Room we’ll be using to get the SD-WAN alerts.

Now that it’s been created, we need to get the Room ID from the WebEx Teams API so the bot knows where to send the messages.

As part of signing up for a WebEx Developer account, you should have access to a personal token that is ephemeral and not permanent. You should be able to go to this URL and list all the rooms you are a member of, then just do a search (Control/Command+F) to find the Alert Room you created.

Copy down the roomId attribute for use with the bot code later.

Create the AWS Lambda Function

For those not familiar with AWS Lambda, consider it an on-demand code execution space. If you wanted to run code to randomly generate a number between 1-20 but didn’t want to maintain a python environment on a server or other infrastructure, you could throw that code in Lambda and execute it there. It could return the answer in any number of ways, though commonly it would reply in the same way it received the request.

For our use case, we want AWS Lambda to take the body of an HTTP POST message (the SD-WAN Webhook), package it up, and then send that to a WebEx Teams room using the Alert Bot’s credentials and targeting the Alert room. To do this, we just need to write some Python.

We have to choose the code language to use as well as name the function. Lambda also supports all sorts of other options that are far too large to explore here. In this case we are using Python. Version 3.8 and after should be fine.

Once we create the code space, we need to add the code. The sample code can be found here in my Github. I had a little help from my good friend Omar Saffouri with the JSON format.

We’ll need the WebEx Bot Token from earlier (bearerToken should have this value) and the WebEx Alert Room ID as well (maps to roomId). We use these in the Lambda code to send the WebEx Teams message but don’t want these variables in plaint text in the editor. Environment variables let us squirrel them away safely from the code itself.

When it’s all said and done, save the Lambda function (by clicking File > Save) and then Deploy the code. The function is ready to intake a message and send that to WebEx Teams! All we need now is some way to take the HTTP POST webhook and get it into AWS Lambda, and for that, we look at the AWS API Gateway.


AWS API Gateway

The basic function of an API is to provide an input/output interface to interact with backend code. As an example, if you go to https://deckofcardsapi.com/ you don’t have access to the code running in the background doing the card shuffling, but if you send a crafted request to the API with specific formats and keywords, the API understands what to do with that information and returns what you ask for.

The code itself, that is, the card-shuffling logic, is a completely separate function from the code someone had to write to create the interactive data structures and keywords to tell the card shuffler what to do. That logic/code is the API. We are going to create a similar front end using AWS serverless architecture. It won’t even have to be complicated because there’s only one input we care about: the HTTP POST from the SDWAN webhook.


We have multiple options when we create an API, including a full REST API from scratch, but because we will only be receiving HTTP POSTs we can make a simple HTTP API.

When creating the HTTP API, it needs to tie together with something. After all, the API Gateway is just a broker between a user and the code. Because the Lambda function was already created, we can just choose it from the dropdown.

A route is basically an API target. The logic is pretty simple. If a POST request comes to <API URL>/sdwan-webhook then forward that HTTP POST body to the Lambda function, which is running our WebEx Teams bot code.

Stages have to do with creating different environments for the API to operate in and are not part of this workflow.

This finishes creating the API Gateway and defines the trigger actions and what should happen when triggered.

If you go back to Lambda you should now see the API Gateway integration. Copy the URL, this is what we will use to point the vManage at to send the webhook.

Setting Up Webhooks in vManage

Webhooks are HTTP POST messages containing some sort of information, usually an alert. vManage supports both email and webhook integration, though it’s still a bit kludgy because in order to make webhooks work we still have to supply dummy email info.

From Administration > Settings we can enable Alarm Notifications. Since we aren’t going to actually send emails, we can leave Email Settings blank.

From Monitor > Logs we can add an Alarm Notification, this is where webhooks are configured.

The alarm level is configurable as are the exact categories.
We can add any dummy email information here (it is required) but the important detail is the webhook URL. This is the same URL we configured for the API gateway. Also, remember that webhooks are sourced from vManage VPN 0 and that it must be able to resolve the URL of the API Gateway to send webhooks. We can actually test this from the vManage command line once the webhook has been saved.

Troubleshooting

From the vManage CLI, run the following test:

  • Drop to the shell with the command vshell
  • Send a test webhook with this command: curl -k -d ‘{“firstName”: “Test”, “lastName”: “Name”}’ -H ‘Content-Type: application/json’ -X POST https://<<YOUR_API_URL>>/sdwan-webhook
  • Hopefully your new WebEx Teams room gets a brand new message!

If not, some simple troubleshooting steps:

  • Test the API Gateway by using Postman from a different computer to rule out the vManage.
  • Verify the Lambda Function received the HTTP POST and what the code did with it via AWS CloudWatch Logs.
  • If Lambda appeared to post the message but got a 404 error, ensure you added the Webex bot to the room! The bot is just like a user and can’t see rooms it wasn’t added to.
That’s all there is to it! I need to point out this API is insecure. Anyone could send a POST to that API and it could end up in your WxT room. There are authorizers available but beyond the scope of this post. You can even designate a Lambda function to perform the authorization. A challenge to expand this might be to inspect the HTTP POST for an expected IP address source and authorize the POST that way, dropping any unknown IP.


1 Comment

anonym · January 11, 2022 at 6:53 am

Awesome! Nice write-up and clever use of Lambda/API GW.

Comments are closed.