The CreatorCon Call for Content is officially open! Get started here.

richardbrounste
ServiceNow Employee
ServiceNow Employee

(note: this solution only works for ServiceNow Jakarta version or later)

Mapping Business Applications automatically is awesome.  With Service Mapping, we can populate the CMDB during the discovery process with servers, software applications and network devices with each one having a direct relationship to a business application. This is incredibly valuable when trying to determine the business application affected from an issue detected on running software or a hardware device.  Or being able to prevent an issue before you are about to make a change to some software or hardware by understanding its business impact.  It allows you to manage Business Application health and view all processes in ServiceNow in context to a business application (Incidents, changes, change requests, unplanned changes, alerts, outages, any custom processes, etc.)

The Service Mapping process finds the components of an application by starting from an entry point like a URL or a Host/Port combination.  The process identifies the running software application on the host and creates the configuration item in the CMDB with a relationship to the Business Service during the discovery process.  After it identifies the running application, it then looks for network dependencies or application references to other hosts from configuration files and starts the process again using that dependency as an entry point.

find_real_file.png

The Service Mapping Process

This process works well for most complex applications. But what if your application has components that don’t have an entry point?  Consider applications that have remote agents that are deployed on a server and perform some important function for a business application on a schedule rather than listening on a port and waiting for a request.  The agent might make an occasional call to another computer to perform a task or report results as part of its designed function but such communication might be impossible to detect if it is not communicating to an application process or if it is not using TCP/IP (like copying a file).  If the agent is not listening on a port or being referenced by another application component, then the traditional method of Service Mapping won’t work.  Yet, we still want to map these agent components as part of our business application. To do so, we need a different approach. We need to identify the components and then find a way to relate them to our Business Application.

find_real_file.png

A Complex Application with Remote Agents that don’t listen on a port are impossible to map automatically with the current Service Mapping Process

SUMMARY OF HOW TO MAP REMOTE AGENTS WITH NO ENTRY POINTS

Here is a summary of an approach that will work to identify and map agent components that aren’t listening on a port or aren’t being referenced by another application component through configuration:

  1. Create a custom CI Class and discovery pattern and use horizontal discovery to inventory the Remote Agents so they are stored in the CMDB
  2. Map the Business application components
  3. Create a custom Discovery Pattern connection section that queries the CMDB for the agent applications and then use that information to connect to and map the Remote Agents.

Now, for the details:

STEP 1: Create a custom CI Type for the Remote Agent and a Custom Discovery Pattern for Horizontal Discovery

We need to get the remote agents into the CMDB.  In order to do that, we need to use horizontal discovery and we need to identify the Agent with a custom discovery pattern.  This is functionality that has existed for a long time in ServiceNow.  I’m going to walk through doing this with a Remote Agent that runs on a machine and does not listen on any port.  First, we need a custom CI Type for the agent.  This is easily done in the CI Class Manager.  Go into Configuration -> CI Class Managerand create a quick CI Type right under the “Application” class by selecting “Add Child Class”:

find_real_file.pngfind_real_file.png

Make note of the Table name (class name) created.  All the other information on the agent class can be kept as the default unless there are other reasons why you need to modify the identification section.  The table name created in my example is “u_cmdb_ci_remote_agent”.  All custom tables always start with a “u_” by the way.

Build a Custom Identification Discovery Pattern

We need to build a custom Discovery Pattern to create the CI for the remote agent.  Go to Pattern Designer -> Discovery Patternsand create a new pattern for the agent:

find_real_file.png

Create an identification section to discover the agent.  Note that since the agent process is not listening on a port, the “Find Process Strategy” must be set to “None”.  The TCP Endpoint and/or HTTP(S) Endpoint are good choices as Entry Point Type since they are simple and generic.  Any dependency connection created only needs to specify the host name.find_real_file.png

find_real_file.png

When defining the steps to identify the Remote Agent, you will need to identify the running process. My example agent is the ServiceNow MID Server process named wrapper-windows-x86-64.exe.  The identification section looks for the process in the output of the “tasklist” command.  This is an important part of the Identification section to uniquely identify the agent process.  The next step will verify that the agent process is there:

find_real_file.png

find_real_file.png

The Remaining steps of the pattern must set the required values for the configuration item in order to create the CI.  The attributes used to identify the CI type must be set. For an Application, it is $running_process_command and $running_process_key_parameters.

find_real_file.png

After you save and publish this discovery pattern, you need to define the process classification so it can be detected during horizontal discovery.  Go to Discovery Definition -> Processes and define a new Process Classification for the Remote Agent Process:

find_real_file.png

And set the Agent Process to run the Remote Agent Discovery Pattern that you just created:

find_real_file.png

Now, when running horizontal discovery on these machines, it will create instances of the Remote Agent in the CMDB running on the servers:

find_real_file.pngfind_real_file.png

STEP 2: Map the Business Application Components

This is the normal Service Mapping process. We now can put in an Entry Point and map the parts of the application that do have entry points…even if it is only a single node:

find_real_file.pngfind_real_file.png

STEP 3: Create a custom Connection Section on an application component to connect to the Agent

This is where we bring it all together.  We need to create a Custom Connectivity Section on one of the Application components that will connect to the Remote Agents that are now stored in the CMDB thanks to horizontal discovery.

find_real_file.pngfind_real_file.png

The connection section called “Connect to Remote Agents” only has 3 steps:

find_real_file.png

find_real_file.png

Step 1  of the pattern section is called “Get Remote Agent Servers”. It is a “Set Parameter Value” operation that uses JavaScript to query the CMDB and gather the Remote Agent Host Names and put them into an array.

 find_real_file.png

To put custom code in the “Value” field, type “EVAL (“ and then the pencil will appear on the screen to edit the code in the expression editor:

find_real_file.png

Here is the code that you can copy and paste:

var num_remote_agent_servers=0;

var remote_agent_servers='';

var remote_agent_ci = new GlideRecord ( "u_cmdb_ci_remote_agent" );

remote_agent_ci.query();

while (remote_agent_ci.next())

  { /* Query all the remote agent software applications */

  var cmdb_rel = new GlideRecord ( "cmdb_rel_ci");

  cmdb_rel.addQuery ( 'parent', remote_agent_ci.sys_id );

  cmdb_rel.query();

  while (cmdb_rel.next())

    { /* query all the relationships for this remote agent software applications */

    var rel_type = new GlideRecord ( "cmdb_rel_type");

    rel_type.get ( cmdb_rel.type );

    if (rel_type.name == "Runs on::Runs")

      { /* now get the hosts on which the remote agent is running */

      var cmdb_cmp = new GlideRecord ( "cmdb_ci_computer");

      cmdb_cmp.get ( cmdb_rel.child );

      num_remote_agent_servers++;

      if (num_remote_agent_servers == 1)

                  remote_agent_servers = cmdb_cmp.name;

      else

                  remote_agent_servers += "," + cmdb_cmp.name;

      } /* now get the hosts on which the remote agent is running */

    } /* query all the relationships for this remote agent software applications */

  } /* Query all the remote agent software applications */

/* very important statement to return the list to the pattern */

rtrn = remote_agent_servers;

 

When code runs in a discovery pattern, it runs on the MID Server.  As of the Jakarta version, it is possible to run code this way that accesses ServiceNow instance tables.  Pre-Jakarta, this would not work.

This code returns a comma-delimited list of servers that are running the custom agent u_cmdb_ci_remote_agent.  Then we can use a simple parsing strategy to put the host names into an array:

find_real_file.png

 

And then create the connection.  We only have host names and no ports but you must put a value in the port field or it won’t save the entry point.

find_real_file.png

Success! Now, when we run the pattern, it will connect to the Remote agents…even though the remote agents are not listening on any port.

find_real_file.png

 

4 Comments