REST API

ServiceNow CMDB REST API Tutorial

In this tutorial we are going to use a practical example to show you how to use the ServiceNow REST API. I personally find ServiceNow has great online documentation but I like to see some examples to understand how other people are using it. This is the motivation for this tutorial and for the previous one on ServiceNow incidents with REST API. Let’s get to it!

Introduction

The CMDB (Configuration Management Database) in ServiceNow is a key component that underpins multiple services. Most organizations nowadays have a requirement to automate services delivery in order to achieve greater agility and efficiency. If we are going to implement automation in ServiceNow sooner or later we need to deal with the CMDB and the way to do this is to use the REST API.

In this tutorial we will explore this by using a Postman collection you can find in this GitHub repo. If you need code in a specific language, Postman can help you generate code for any of the API calls in the collection. The collection also contains REST API calls to manage Incidents in ServiceNow. These calls were used in a previous tutorial called “Creating ServiceNow Incidents via REST API” which showed some examples on how to address one of the most common tasks organizations are willing to automate in ServiceNow.

If you are reading this more than likely you know what a CMDB now, so I won’t provide much detail here. The main thing to know is that the CMDB is organized in a large hierarchy of tables. At the top of the hierarchy we have the “cmdb” table and from that a single child called “cmdb_ci”. This last table is the parent for everything else. (services, applications, servers, networks, databases …).

All objects in this database are called “Configuration Items” or “CI” for short. You can show all the items by typing “cmdb_ci.list” in the “Navigator”. My developer instance has more than 2800 CI’s. The “class” parameter tells us what type of CI it is and as you will see it is a very important detail when dealing with the REST API.

The CMDB is accessed in the ServiceNow interface with the “configuration” application. Once you type “configuration” in the “Navigator” you can scroll down to see everything it contains.

The REST API

When working with a new REST API, the first step is to learn how to authenticate. In that regard, the ServiceNow REST API is straight forward as you can use basic authentication, ie username and password.

There are two main tools available to learn what API calls are available: the online product documentation and the REST API Explorer. In the online documentation you have to find the “REST API Reference” and then scroll down to “CMDB Instance API“. This is publicly accessible. In the following screenshot you can see it contains 7 REST API calls that allow you to do a range of CRUD operations.

Notice how the API calls have the “classname” URL parameter. This corresponds to the “class” we mentioned earlier. Every piece of information one would expect to find (parameters, headers, status codes …) is provided in this documentation

The second tool is the “REST API Explorer”. This a a great tool that allows you to build your API calls in a graphical manner, including the “body” payload for POST /PUT/PATCH calls. I showed how to use it in the previous tutorial “Creating ServiceNow Incidents via REST API“. However, given the sheer amount of attributes available for all classes of CI’s I am going to suggest a different way of doing this

Learning with a practical example

Let’s say we have an automation script that creates and configures a Linux virtual machine and as part of the same script now we want to add an entry for the virtual machine in the CMDB. The following API call is the one we need to use in order to create the CI:

POST /now/cmdb/instance/cmdb_ci_linux_server

This POST call requires a request “body” parameter which can have a large number of attributes as well as inbound/outbound relation information, ie how this CI is related to other CI’s. To help us configure the “body” we are going to:

  • create manually a sample resource of the same class (ie. a Linux server in this case) and configure it the way we need it. It is important to configure every attribute we want to use
  • use a GET call for that resource. The response will serve you as a very good reference for the “body” of the POST call we want to automate

We type “configuration” and scroll down to “Servers” and click on “Linux”. Once in “Linux Servers”, click “New” to create a new Linux server. I have filled in those fields that are relevant to my use case.

Once ready, you can click submit and the new CI will be created.

At this point, you might want to add information on how this CI is related to other CI’s. This will be very useful for example to see what services/applications are impacted if there is an incident on this CI. In my example let’s say I want to show that this Linux server depends on a storage volume. Follow these steps:

  • Open the CI you have just created
  • Scroll down to “Related Items”
  • On the right click the “+” symbol next to “Search for CI” to open the “Relationship Editor”

This opens the “Relationship Editor” as seen below. Now you can select the type of relationship and use the filter tool to search for the CI it depends on, ie a storage volume in our example. Then tick the CI and click the “+” symbol to add the relationship

In my case I have also created an additional relationship with an application named “Alberto Inventory app”. For the application I chose the “Used by” relationship, meaning that the application is the one that “depends on” the Linux server. In the resulting “Relationships” table below you can see both relationships and the parent/child relationship:

Back in Linux server record we can see at a glance the resulting relationships in the “Related Items” section. Notice how this is showing an additional relationship “Used by – Alberto Inventory Service”. I didn’t explicitly declared this relationship but I had an existing relationship between this service and the application. So in the end the service also depends on this Linux server

Now it is time to use Postman to see what the payload looks like. Download the collection and create 2 environment variables “pwd” and “instance” as instructed in the GitHub repo. At this point you can open the “Get CMDB Linux servers” call and click “Send”. This will return a list of Linux servers. But for each of them only the “sys_id” and the “name” are displayed.

Copy the the “sys_id” of your newly created Linux server CI and open the “GET CMDB Linux server details” call in Postman. In the URL you can the “sys_id” to the end of the URL (see highlighted in yellow) and click “Send”

This is now showing a very good approximation of the “body” parameter we were after including attributes as well as inbound/outbound relations. Notice though, how it is nested under “result”. Notice also how the JSON payload is showing all the attributes, including attributes were not displayed in the form when we created the resource. Any attribute we didn’t specify during CI creation will be empty. At this point you can make a note of any extra attributes you want to include in your payload.

Now in Postman let’s open the “select the “POST Create CMDB Linux server” call. This will create a second server called “alblinux02” with the same relationships as the server we created manually. Open the “Body” tab to see the JSON payload.

The most significant change we need to make to the output of the GET call is to modify those attributes whose value was a “dictionary” with three keys (“display_value”, “link” and “value”). These kind of attributes are in the “attributes” section as well as in the “inbound and outbound relations” sections. What we need to do is to replace the whole dictionary value with just the “sys_id” which happens to be the “value” field in the GET call output

Now we can click “Send” and the new Linux server CI will be created. You will get the status code “201 Created”. Now in the Linux servers app you should see both Linux servers.

And if you want to see the whole stack end-to-end you can go to the “application” and click on “Show Dependency views”

Supplementary API calls

You might have noticed in the request “Body” of the POST call that I included several “sys_id”. While you can get “sys_id” in the ServiceNow GUI by using right-click, ultimately if you want to automate a process you will have to get that information programmatically. For that purpose the Postman collection includes three API calls to help you get “sys_id” you need:

  • CMDB relationship types
  • CMDB users
  • CMDB CI

In the screenshot below you can see the three supplementary API calls highlighted in yellow. In the response to the “relationship types” call you would have to locate the item in the list with the “name” of the relationship you need and then extract its “sys_id”.

The process is very similar if you need to extract the “sys_id” of a “user” or a “CI” with the other two API calls

Tips and tricks

It might happen that when you build the payload for a POST call, like the “Create CMDB Linux server” you might accidentally omit a mandatory attribute. You could go to the documentation to see what the mandatory attributes are, but one thing I found really useful is that the ServiceNow REST API let’s you know what you are missing in the error message. In the screenshot below I removed the “discovery_source” attribute and sent the API call. As you can see the error message let’s me know exactly what the problem is.

One thing to bear in mind is that by default GET api calls return only 1000 records. If you are looking for a certain “CI” in order to extract its “sys_id” it might well happen that you have more than 1000 CI’s in the CMDB and the CI is not in the output. In that case you can use the “sysparm_query” parameters to narrow down the search or use the parameter “sysparm_limit” to retrieve more than 1000 records. You will notice in the Postman collection how the “Get CMDB CI” call is using “sysparm_limit” to retrieve 10000 records.

That was a long post! Thanks for putting up with me for the last 15 mins 😉 I hope you found this tutorial useful.

2 replies »

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.