How To Map and Sync Statuses and Correlation Details Between Azure DevOps and ServiceNow

ServiceNow Azure DevOps integration

In this blog, we are going to discuss a commonly asked Azure DevOps ServiceNow integration use case.

The primary objective of this use case is to sync statuses and exchange correlation details between Azure DevOps and ServiceNow using a third-party integration tool. For this integration, I have used a tool called Exalate.

Here are the requirements and challenges:

The Use Case Requirements

When a user opens an incident on ServiceNow, the description, attachment, and status should be automatically synced over to the corresponding work item in Azure DevOps.

In addition to these primary requirements, we want to sync the following:

  • Map statuses bi-directionally between Azure DevOps and ServiceNow. For instance, “Active” is mapped to “In Progress”.
  • Sync these statuses bi-directionally between Azure DevOps and ServiceNow.
  • When a status is marked as “Closed” in Azure DevOps, a corresponding close code and close note is added in the ServiceNow instance and the status is changed to “Resolved”.
  • Display the Azure DevOps work item ID in the Correlation ID field in ServiceNow.
exalate connector

Potential Challenges

  • Avoiding errors when writing sync rules for the incoming and outgoing data. 
  • Setting up the right triggers to update the fields on both sides automatically.
  • Mapping the correct fields and entities.
  • Fetching the correct work item ID and populating the ServiceNow Correlation ID field.
  • Handling possible network timeouts.

Solution to the Problem: Exalate

Exalate is a bi-directional integration solution that works with Zendesk, Azure DevOps, ServiceNow, Jira, Salesforce, etc. 

It has a Groovy engine that allows developers and scripting enthusiasts to write sync rules for each connection.

How to Implement Exalate for Automatic Data Syncs

First, you need to install Exalate on both Azure DevOps and ServiceNow. 

Next, establish a connection between them using the Script Mode—which enables the advanced integration that this use case demands. 

Then, open the Exalate console in your ServiceNow dashboard. Go to the connection you want to edit, and click the “Edit connection” icon. 

You have two options: 

  • Outgoing sync (on the ServiceNow side) refers to the data to be sent over to the Azure DevOps side. 
  • Incoming sync (on the Azure DevOps side) refers to the data to be received from the incident on ServiceNow.

Under the “Rules” tab, enter the following code snippet into the “Outgoing sync” text area. 

exalate outgoing sync
if(entity.tableName == "incident") {
    replica.key            = entity.key
    replica.summary        = entity.short_description
    replica.description    = entity.description
    replica.attachments    = entity.attachments
    replica.comments       = entity.comments
    replica.state          = entity.state
    replica.entityType = "incident"
}}

Note: The expression above establishes the mappings for every ServiceNow entity type. For this use case, we sync an “incident” within the ServiceNow environment. You can add additional ServiceNow entities in the Outgoing sync. You can see that the sync rules in the console allow you to sync statuses, comments, attachments, descriptions, keys, and short descriptions. 

Scroll down to the incoming sync and enter the following code:

if(firstSync){
    if (replica.type.name == "Task")
        entity.tableName = "incident"
    syncHelper.syncBackAfterProcessing()
}

if(entity.tableName == "incident") { 
    entity.short_description = replica.summary
    entity.description = replica.description
    entity.attachments += replica.addedAttachments
    entity.comments += replica.addedComments
    
    def statusMapping = ["Active":"In Progress", "Closed":"Resolved"]
    def remoteStatusName = replica.status.name
    if (remoteStatusName == "Closed"){
        entity.close_code = "Known Error"
        entity.close_notes = "Closed by Azure DevOps"
    }
    entity.state = statusMapping[remoteStatusName] ?: remoteStatusName
    entity.correlation_id = replica.key
}

if(entity.tableName == "cmdb_ci_business_app") { 
    entity.short_description = replica.summary
    entity.description = replica.description
}

Note: The code snippet above establishes the status mappings and the Correlation ID details. You can also display the remote entity URL in the Correlation Display field. 

In ServiceNow, close notes and close code notes are mandatory fields. So you need to add them when the work item status on Azure DevOps is closed.

Once done, click “Publish” to save the changes.

On the Azure DevOps side, enter the code in the “Incoming sync” text area.

exalate incoming sync
if(firstSync){
   // Set type name from source entity, if not found set a default
   workItem.projectKey  =  "Test Project"
   if (replica.entityType == "incident")
        workItem.typeName = "Task";
    syncHelper.syncBackAfterProcessing()
    
}

workItem.summary      = replica.summary
workItem.description  = replica.description
workItem.attachments  = attachmentHelper.mergeAttachments(workItem, replica)
workItem.comments     = commentHelper.mergeComments(workItem, replica)
workItem.labels       = replica.labels
workItem.priority     = replica.priority



def statusMapping = ["In Progress":"Doing", "New":"To Do", "Resolved":"Done"]
def remoteStatusName = replica.state
workItem.setStatus(statusMapping[remoteStatusName])

The code snippet defines the mapping rules for states and statuses. So if the incident is “In Progress,” it will appear as “Doing” in the corresponding work item. “New” becomes “To Do,” and “Resolved” becomes “Done”.

Scroll down to the outgoing sync field and enter the following code:

replica.key            = workItem.key
replica.assignee       = workItem.assignee 
replica.summary        = workItem.summary
replica.description    = nodeHelper.stripHtml(workItem.description)
replica.type           = workItem.type
replica.status         = workItem.status
replica.labels         = workItem.labels
replica.priority       = workItem.priority
replica.comments       = nodeHelper.stripHtmlFromComments(workItem.comments)
replica.attachments    = workItem.attachments
replica.project        = workItem.project
replica.areaPath       = workItem.areaPath
replica.iterationPath  = workItem.iterationPath

Note: The code snippet above sends work item related information (summary, assignee, etc.) to the other side (ServiceNow). 

Once done, click “Publish” to save the changes.

Congratulations! You have now set rules for syncing data between Azure DevOps and ServiceNow. 

Subsequently, you can adjust the rules according to the demands of specific projects and issues.

So, let’s see how it works in practice.

exalate rules adjustment

When you sync an incident and a work item, the work item ID gets reflected in the Correlation ID field in ServiceNow. 

Enter the description and add a comment to the incident.

exalate sync incident

Go over to the Azure DevOps side. You’ll see that the same comment has come over, as well as the description. Also, since the incident’s state is “New”, the task status will reflect ”To Do” as well.

exalate azure devops

Next, upload an attachment and respond to the comment. Then change the incident state to “In Progress” and then to “Resolved”. 

exalate resolved issue

Back on Azure DevOps, you can review the task history to see all the changes that have taken place on the incident.

exalate task history

And that’s all you need to get this use case working!

Conclusion

Exalate allows you to sync data between ServiceNow incidents and Azure DevOps work items. You can specify the rules according to each use case. 

If you still have questions or want to see how Exalate is tailored to your specific use case, book a demo with one of our experts immediately.

Recommended Reading:

Comments are closed.