Deploy a ChatOps solution for creating events and incidents

ChatOps is the integration of development tools, operations tools, and processes into a collaboration platform so that teams can efficiently communicate and easily manage the flow of their work.

ChatOps allows instant collaboration with subject matter experts (operators, SREs, DevOps engineers, and developers) among themselves and with other applications through bots. Read more about ChatOps and virtual war rooms in the IBM Garage Practices. In the context of this tutorial, ChatOps helps teams works on problems faster (improving the “mean time to repair”).

IBM Cloud Event Management enables you to manage events and incidents when there is an operational problem. This component is available to provision in these ways:

  • An independent SaaS service
  • An IBM Cloud service
  • As part of the Monitoring Module of Cloud Pak for Multicloud Management.

Cloud Event Management comes with ChatOps integration that you can use to forward events into Slack but not to create events from Slack. With this tutorial, you can extend Cloud Event Management and develop a complete ChatOps solution by creating events from within a Slack channel.

The Cloud Event Management Slack bot interface looks like this:

CEM Slack bot interface

The event that is created from using the Slack bot interface looks like this in the Cloud Event Management UI:

CEM Event in the Cloud Event Management UI

Learning objectives

In this tutorial, you will learn how to:

  • Create an incoming webhook integration in Cloud Event Management
  • Create IBM Cloud Functions that will integrate with that webhook
  • Integrate a Slack workspace with Cloud Event Management using IBM Cloud Functions.

Prerequisites

Estimated time

After you’ve installed and configured the prerequisite software, it should take you approximately 30 minutes to complete the tutorial.

Architecture

The following diagram shows the workflow for a Slack bot that creates Cloud Event Management events.

arch flow

  1. The user executes the slash command /cemcreate in the Slack channel.
  2. The Slack server calls an IBM Cloud Function to create the dialog screen.
  3. The user clicks “submit,” and the data is returned to the Slack server.
  4. The Slack server calls an IBM Cloud Function to process the data.
  5. The Cloud Function creates an event in Cloud Event Management.

Steps

Create a Cloud Event Management integration

  1. Log in to your IBM Cloud Event Management instance. Click the Administration tab.

    For an instance deployed on IBM Cloud, the URL for this tab might be: https://console.us-south.cloudeventmanagement.cloud.ibm.com/administration?cmsp=ibmdev--developer-tutorials-_-cloudreg.

  2. Click the Integrations Hexagon.

  3. Click the New Integration button to view the list of possible integrations.

  4. Make sure that you are on the Incoming tab. Scroll down to the Webhook integration, and click Configure.

List of integrations highlighting webhook integration

  1. Specify a name for your webhook. For example, use CEM-ChatOps.

  2. In the Example incoming request box, copy and paste the following JSON sample:

{
  "Severity": "Critical",
  "Summary": "This is my message",
  "ResourceName": "ServerA",
  "EventType": "standard"
}
  • Complete the mandatory Event attributes with the following values:

    • Severity : Severity
    • Summary : Summary
    • Resource Name : ResourceName
    • Event Type : EventType
  • Copy and record the URL of the Webhook endpoint.

  • Make sure that the Enable toggle is set to On.

API Key credentials

  • Click Save.

At this point you have a working incoming Webhook integration.

Create and test the back-end Cloud Function

  1. Open a new tab in your browser and navigate to IBM Cloud Functions.

  2. Click Log in to IBM Cloud and sign into your IBM Cloud account. You are redirected back to the IBM Cloud Functions home page. If you are not redirected, go to https://cloud.ibm.com/functions/.

  3. Click Start Creating. If this is the first time you are using IBM Cloud, you might get a message requesting that you create a namespace.

  4. Select Action. Specify a name for your action. For example, cem-chatops-backend. Then, choose the Python 3.x runtime. Leave the rest of the fields with the default options.

    Cloud Functions action creation page

  5. Click Create.

    Your new function is ready.

    Cloud Functions boilerplate code page

  6. Click the Parameters tab in the left nav. Click Add parameter, and add a parameter called cem_url for the function. For the parameter value, specify the Cloud Event Management Webhook URL that you recorded earlier.

    Cloud Functions parameters after filling in

  7. Move to the Endpoints tab and activate the Enable as Web Action option. This will enable Slack to access the Cloud Function.

  8. Record the webhook URL. You will use it soon.

    Cloud Functions endpoint page

  9. Return to the Code tab. Then, copy and paste the following code into the function.

     #
     # This function will be triggered by Slack
     #
    
     import sys, json, requests
    
     def main(dict):
    
         print("function begins")
         print(dict)
    
         if 'challenge' in dict.keys():
             return {"challenge" : dict['challenge']}
    
         if 'payload' not in dict.keys():
             return {"message":"Invalid message, payload not found"}
    
         d = dict['payload']
         if 'type' not in d.keys() or 'callback_id' not in d.keys():
             return {'message':"Invalid message, payload missing fields"}
    
         if d['type'] == 'dialog_submission' and d['callback_id'] == 'CreateCEMIncident':
             print ("create_cem_event begins")
    
             url = dict['cem_url']
             headers = {'Content-Type': 'application/json'}
    
             payload ={
                 "severity": d['submission']['severity'],
                 "summary":  d['submission']['summary'],
                 "resource": d['submission']['resource'],
                 "type":     d['submission']['type']
             }
    
             response = requests.post(url, data=json.dumps(payload), headers=headers)
    
             responseJson = json.loads(response.text)
             print (responseJson)
    
             print ("create_cem_event ends")
    
             return {responseJson}
    
         else:
             return {'message':'No work done'}
    
  10. To test your back-end Cloud Function, run the following command from your command line (replacing webhookurl with the relevant value):

    `curl -X POST -d '{"payload":{"type":"dialog_submission","callback_id":"CreateCEMIncident","submission":{"severity":"Critical","summary":"My test message","resource":"Server","type":"standard"}}}' <webhookurl>.json`
    

    You should see a response similar to this:

    {
    "deduplicationKey": "609938c8259f1fbf8343a75611e11cbc",
    "eventid": "41e48940-b3cf-11ea-83a2-371d430da290"
    }
    

Another way to validate that your back-end Cloud Function is working is to view the Incident list in Cloud Event Management. In an IBM Cloud SaaS instance of Cloud Event Management hosted in IBM US-South, the link will be at https://console.us-south.cloudeventmanagement.cloud.ibm.com/incident-queue/all. If you are hosting Cloud Event Management in Cloud Pak for Multicloud Management you will use your own URL.

Create the front-end Cloud Function

Repeat the above steps to create a Cloud Function called cem-chatops-frontend.

Generate and record an Endpoint for the function.

Create two parameters cemUI and slackToken. Leave them empty (“”) for now.

Paste the following code into the Code tab for this front-end Cloud Function:

    #
    #

    # This will create a dialog. When the dialog is filled, the data will be sent to the back-end function.

import sys
import os, json, requests

def main(dict):

    print (dict)

    if 'warmup' in dict.keys():
        return { "warmup": 1}

    if 'payload' in dict.keys():
        return {
            "response_type": "ephemeral",
            "replace_original": False,
            "text":  "Command recieved with id " + dict['trigger_id']
        }        
    else:
        openDialog(dict)
        return {
            "icon_emoji": ":csmo:",
            "response_type": "ephemeral",
            "replace_original": False,
            "text":  "Creating event, sent to <" + dict['cemUI'] + "|CEM>"
        }        

def openDialog(dict):

    url = "https://slack.com/api/dialog.open"

    payload={
        "trigger_id": dict["trigger_id"],
        "dialog": {
            "callback_id": "CreateCEMIncident",
            "title": "Send an event to CEM",
            "submit_label": "Create",
            "state": "Limo",
            "elements": [
            {
              "type": "text",
              "label": "Event Summary",
              "name": "summary"
            },
            {
              "type": "text",
              "label": "Affected resource",
              "name": "resource"

            },            {
              "type": "text",
              "label": "Affected resource type",
              "name": "resourceType",
              "optional" : True
            },            {
                "label":"Severity",
                "type":"select",
                "name":"severity",
                "value":"Critical",
                "options" : [
                    {
                        "label" : "Critical",
                        "value" : "Critical"
                    },
                    {
                        "label" : "Major",
                        "value" : "Major"
                    },
                    {
                        "label" : "Minor",
                        "value" : "Minor"
                    },
                    {
                        "label" : "Warning",
                        "value" : "Warning"
                    },
                    {
                        "label" : "Information",
                        "value" : "Information"
                    },
                    {
                        "label" : "Indeterminate",
                        "value" : "Indeterminate"
                    }
                ]
            },
            {
                "label" : "Event Type",
                "name"  : "type",
                "value" : "regular",
                "type"  : "text"
            }
        ]
     }
    }

    auth_token = 'Bearer ' + dict['slackToken']
    response = requests.post(url, data=json.dumps(payload), headers={'Content-Type': 'application/json;charset=utf-8', 'Authorization': auth_token })
    print(response.text) #TEXT/HTML

Create a Slack bot and integrate with the Cloud Functions

  1. Sign in to your Slack workspace. Enter your workspace URL name and press Enter.

  2. Go to api.slack.com, and click the Start Building button.

  3. Name your Slack bot

    Slack bot name

  4. In the left nav, go to the Interactivity & Shortcuts tab, set the toggle to On, and fill in the URL of the endpoint of the backend Cloud Function, and click Save Changes.

    Interactivity & Shortcuts

  5. Go to the Slash Commands tab, and click the Create New Command button.

    Create New Command

  6. Fill in the Command Name and Short Description. For the Request URL fill in the URL of the endpoint of the front-end Cloud Function. In this case you must add .json to the endpoint name. Click Save.

    Fill details

  7. Go to the Install App tab, and click the Install App to Workspace button.

    Install App

  8. On the dialog that is displayed, click the Allow button to allow the relevant permissions for the new Slack bot.

    permissions

  9. Record the access token you receive after the bot has been installed to the Slack workspace.

    token

  10. Go back to the front-end Cloud Function (cem-chatops-frontend), and update the parameters:

    cem-chatops-frontend parameters

Create Cloud Event Management incidents

  1. Go to any channel in your Slack workspace, and run the slash command you defined to create a Cloud Event Management event: /cemcreate

  2. In the dialog that is displayed, fill it with relevant values.

    Slack dialog

  3. Click Create. The following response is displayed in your Slack channel:

    Slack response

  4. Click the CEM link in that response. The Cloud Event Management UI is launched to show you the list of incidents, including your new one!

Summary

In this tutorial, you learned how to use IBM Cloud Functions to integrate a Slack bot with IBM Cloud Event Management. You can read more about how to implement ChatOps in a Service Management Architecture in the IBM Cloud Garage.

Want to explore what’s beyond ChatOps? Check out AIOps where you apply artificial intelligence to your IT operations and events, and discover how you might include IBM Watson AIOps into your next ChatOps solution.