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.
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.
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.
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.
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.
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.
Next, upload an attachment and respond to the comment. Then change the incident state to “In Progress” and then to “Resolved”.
Back on Azure DevOps, you can review the task history to see all the changes that have taken place on the incident.
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:
- How to Synchronize User Mentions in Comments Between Jira Cloud and Jira On-premise
- How to Synchronize a Zendesk Ticket to Multiple Jira Cloud Instances
- Advanced Integration Use Cases
- How to Sync Tempo Worklogs Between Two Jira Cloud Instances
- How to Sync Custom List Fields Bi-Directionally Between Jira and Zendesk