The ServiceNow Azure DevOps integration bridges development and operations by connecting work items, builds, and releases with ServiceNow's change management and configuration management processes. This integration enables organizations to maintain traceability between code changes and business requirements while enforcing governance through automated approval gates and CMDB synchronization. Development teams, release managers, and IT operations staff rely on this integration to streamline DevOps workflows while maintaining audit trails and compliance requirements. The integration supports bi-directional data flow between Azure DevOps work items and ServiceNow change requests, with automated triggering through webhooks and scheduled imports. Primary automation patterns include pipeline approval gates that query ServiceNow change request states, automatic linking of commits to change requests via commit message parsing, and real-time synchronization of release information to Configuration Items in the CMDB. The integration leverages ServiceNow's Integration Hub Azure DevOps spoke and operates within the DevOps module.
Prerequisites
- •ServiceNow Vancouver or later with Integration Hub Professional license
- •Azure DevOps Services or Azure DevOps Server 2020 or later
- •Azure DevOps project administrator permissions to create Personal Access Tokens
- •ServiceNow admin role or integration_admin role for spoke configuration
- •DevOps plugin (com.snc.devops.core) activated in ServiceNow
- •MID Server installed and running if connecting to on-premises Azure DevOps Server
- •Change Management plugin activated for change request linking functionality
Architecture Overview
The integration uses the official ServiceNow Integration Hub Azure DevOps spoke (com.sn_azure_devops_spoke) which provides pre-built actions for work item management, build monitoring, and release tracking. Authentication is established through Personal Access Tokens stored in ServiceNow Connection & Credential Alias records, with the spoke handling OAuth 2.0 token refresh automatically when using Azure Active Directory authentication. Data flows bi-directionally with outbound calls from ServiceNow to Azure DevOps using RESTMessageV2 calls through the spoke actions, and inbound data via scheduled Transform Maps that import work items, builds, and releases. A MID Server is required only when connecting to on-premises Azure DevOps Server instances, while Azure DevOps Services connections run directly through ServiceNow's cloud infrastructure. The Azure DevOps REST API enforces rate limits of 10,000 requests per 10 minutes per organization, and the spoke includes built-in throttling and retry logic to handle these constraints gracefully.
Sourdough: ServiceNow Monitoring and Analytics
A Chrome extension for ServiceNow Admins and Developers with essential tools, analytics, graphs and monitoring features.
Free to install. Pro $5/month after a 14-day no-card trial.
Pro requires the ServiceNow admin role. Upgrade inside the extension.
Implementation Steps
Create Azure DevOps Personal Access Token and Connection Alias
In Azure DevOps, navigate to User Settings > Personal Access Tokens and create a new token with Full Access scope or minimum scopes of Work Items (read/write), Build (read), Release (read), and Code (read). Copy the generated token immediately as it won't be displayed again. In ServiceNow, navigate to Connections & Credentials > Connection & Credential Aliases and click New to create a new alias. Set the Name field to 'Azure DevOps Connection', Type to 'HTTP(S)', and in the Connection section, enter your Azure DevOps organization URL (https://dev.azure.com/yourorg). Create a new Basic Auth credential with the username as your Azure DevOps email and password as the PAT token you generated.
Install and Configure Azure DevOps Integration Hub Spoke
Navigate to System Applications > All Available Applications > All and search for 'Azure DevOps Spoke'. Install the spoke if not already present, which will add the com.sn_azure_devops_spoke application to your instance. After installation, go to Integration Hub > Connections and verify the Azure DevOps connection appears in the available connection types. Navigate to Integration Hub > Action Designer and confirm that Azure DevOps actions are available, including 'Get Work Item', 'Create Work Item', 'Update Work Item', and 'Get Build Details'. Test the connection by creating a simple flow that calls the 'Get Projects' action using your connection alias.
Configure Work Item to Change Request Mapping
Navigate to DevOps > Administration > Tool Configurations and create a new Azure DevOps tool configuration. Enter your Azure DevOps organization URL, select the connection alias created in step 1, and specify the project name you want to integrate. In the Mapping tab, configure the work item type mapping by selecting which Azure DevOps work item types (User Story, Bug, Task) should map to ServiceNow change request types (Standard, Emergency, Normal). Set up field mappings between Azure DevOps fields like Title, Description, State, and Assigned To with corresponding ServiceNow change request fields. Enable bi-directional sync to allow updates in either system to reflect in the other.
// Transform Map script to sync Azure DevOps work item to Change Request
var changeGR = new GlideRecord('change_request');
changeGR.initialize();
changeGR.short_description = source.title || 'Azure DevOps Work Item: ' + source.id;
changeGR.description = source.description || '';
changeGR.state = source.state == 'Active' ? '2' : '1'; // Map states appropriately
changeGR.assignment_group = 'your_assignment_group_sys_id';
changeGR.u_azure_devops_id = source.id; // Custom field to store work item ID
var changeSysId = changeGR.insert();
target.change_request = changeSysId;Set Up Pipeline Approval Gates Integration
Create a Scripted REST API in ServiceNow by navigating to System Web Services > Scripted Web Services > Scripted REST APIs. Create a new API named 'Azure DevOps Pipeline Approval' with the path 'azuredevops/approval/{change_number}'. Implement a GET method that queries the change request status and returns approval/rejection status in JSON format expected by Azure DevOps release gates. In Azure DevOps, navigate to your release pipeline and add a new Agentless job with an 'Invoke REST API' task that calls your ServiceNow endpoint. Configure the gate to poll every 5 minutes with a timeout of 60 minutes, parsing the JSON response to determine if the pipeline should proceed based on change request state.
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var changeNumber = request.pathParams.change_number;
var changeGR = new GlideRecord('change_request');
changeGR.addQuery('number', changeNumber);
changeGR.query();
var result = {
approved: false,
message: 'Change request not found'
};
if (changeGR.next()) {
var state = changeGR.getValue('state');
result.approved = (state == '1' || state == '2'); // Approved states
result.message = 'Change request ' + changeNumber + ' is in state: ' + changeGR.getDisplayValue('state');
result.change_sys_id = changeGR.getUniqueValue();
}
response.setStatus(200);
response.setHeader('Content-Type', 'application/json');
response.getStreamWriter().writeString(JSON.stringify(result));
})(request, response);Configure Release Notes Synchronization to CMDB
Navigate to Integration Hub > Flow Designer and create a new flow named 'Sync Azure DevOps Release to CMDB'. Set the trigger to run on a schedule (every 15 minutes) and add an Azure DevOps spoke action 'Get Releases' to retrieve recent releases from your configured project. Add a ForEach loop to process each release and use the 'Get Release Details' action to fetch complete release information including release notes and deployed artifacts. Create or update Configuration Items in the CMDB by adding a 'Create Record' action targeting the cmdb_ci_appl table, mapping release name to CI name, release notes to description, and release date to install_date. Include error handling by adding a conditional that checks if the Azure DevOps API call was successful before attempting CMDB updates.
// Flow Designer script step to process release data
var releaseData = fd_data.lookup('azure_devops_release');
var ciGR = new GlideRecord('cmdb_ci_appl');
ciGR.addQuery('u_release_id', releaseData.id); // Custom field for tracking
ciGR.query();
if (!ciGR.hasNext()) {
ciGR.initialize();
ciGR.name = releaseData.name;
ciGR.u_release_id = releaseData.id;
ciGR.short_description = 'Azure DevOps Release: ' + releaseData.name;
ciGR.description = releaseData.description || '';
ciGR.install_date = new GlideDateTime(releaseData.createdOn);
ciGR.version = releaseData.releaseDefinition.revision;
ciGR.operational_status = releaseData.status == 'succeeded' ? '1' : '6';
ciGR.insert();
fd_data.setValue('ci_created', true);
}Implement Commit Message Change Request Linking
Create a Business Rule on the change_request table that generates a unique commit prefix for each change request, storing it in a custom field u_commit_prefix. Navigate to System Definition > Business Rules and create a new rule triggered 'after insert' that generates a prefix like 'CHG0030001-' for easy identification in commit messages. Set up a scheduled job (System Definition > Scheduled Jobs) that runs every 10 minutes to query Azure DevOps Git repositories for commits containing change request numbers in their messages. Use the Azure DevOps spoke 'Get Commits' action with a date filter to retrieve recent commits and parse commit messages using regex to extract change request numbers. When matches are found, create entries in a custom table 'u_devops_commits' linking the commit SHA, change request, and commit details for traceability.
// Business Rule to parse commits and link to change requests
var commits = JSON.parse(response.body).value; // From Azure DevOps API response
for (var i = 0; i < commits.length; i++) {
var commit = commits[i];
var message = commit.comment || '';
var changePattern = /CHG\d{7}/gi;
var matches = message.match(changePattern);
if (matches && matches.length > 0) {
for (var j = 0; j < matches.length; j++) {
var changeGR = new GlideRecord('change_request');
changeGR.addQuery('number', matches[j]);
changeGR.query();
if (changeGR.next()) {
var linkGR = new GlideRecord('u_devops_commits');
linkGR.initialize();
linkGR.u_change_request = changeGR.getUniqueValue();
linkGR.u_commit_id = commit.commitId;
linkGR.u_commit_message = commit.comment;
linkGR.u_author = commit.author.name;
linkGR.u_commit_date = new GlideDateTime(commit.author.date);
linkGR.insert();
}
}
}
}Configure Build Status Integration and Testing
Create an Integration Hub flow to monitor Azure DevOps build status and update related change requests automatically. Use the 'Get Builds' spoke action with a filter for builds modified in the last hour, then loop through results to identify builds linked to change requests through work items or commit messages. Add conditional logic to update change request work notes with build status, setting appropriate states based on build success or failure. In the change request form, add a related list to display linked commits from the custom table created in step 6. Test the complete integration by creating a change request, committing code with the change number in the message, triggering a build, and verifying that build status appears in the change request work notes and that the commit link is visible in the related list.
// Flow script to update change request with build status
var buildData = fd_data.lookup('build_result');
var workItems = buildData.work_items || [];
for (var k = 0; k < workItems.length; k++) {
var workItemId = workItems[k].id;
var changeGR = new GlideRecord('change_request');
changeGR.addQuery('u_azure_devops_id', workItemId);
changeGR.query();
if (changeGR.next()) {
var statusMsg = 'Build ' + buildData.buildNumber + ' ';
statusMsg += (buildData.status == 'succeeded') ? 'completed successfully' : 'failed';
statusMsg += ' on ' + new GlideDateTime().getDisplayValue();
changeGR.work_notes = statusMsg;
if (buildData.status == 'failed' && changeGR.state == '2') {
changeGR.state = '4'; // Set to Assess if build fails
}
changeGR.update();
}
}Set Up Monitoring and Error Handling
Navigate to Integration Hub > Action History to create monitoring dashboards for Azure DevOps spoke action executions, setting up alerts for failed actions that exceed normal thresholds. Create custom Business Rules on integration tables to log errors and send notifications when critical synchronization failures occur, such as when change requests cannot be updated due to workflow restrictions or when Azure DevOps API calls consistently fail. Set up Log Analytics by configuring custom log sources in System Logs > Log Reading > Log File to capture Azure DevOps integration-specific messages. Implement a health check endpoint by extending the Scripted REST API from step 4 to include connectivity testing and integration status reporting. Document all custom fields, tables, and configurations created during the integration setup for future maintenance and troubleshooting purposes.
// Health check script for monitoring integration status
var healthCheck = {
azure_devops_connection: false,
last_sync_time: null,
error_count_24h: 0,
status: 'unknown'
};
try {
// Test Azure DevOps connection
var testConn = new sn_ws.RESTMessageV2('Azure DevOps Test', 'GET');
var response = testConn.execute();
healthCheck.azure_devops_connection = (response.getStatusCode() == 200);
// Check recent sync activity
var syncGR = new GlideRecord('u_devops_commits');
syncGR.orderByDesc('sys_created_on');
syncGR.setLimit(1);
syncGR.query();
if (syncGR.next()) {
healthCheck.last_sync_time = syncGR.getValue('sys_created_on');
}
// Count recent errors
var errorGR = new GlideAggregate('syslog');
errorGR.addQuery('source', 'CONTAINS', 'azure_devops');
errorGR.addQuery('level', 'error');
errorGR.addQuery('sys_created_on', '>', gs.daysAgoStart(1));
errorGR.addAggregate('COUNT');
errorGR.query();
if (errorGR.next()) {
healthCheck.error_count_24h = parseInt(errorGR.getAggregate('COUNT'));
}
healthCheck.status = 'healthy';
} catch (e) {
healthCheck.status = 'error: ' + e.message;
}
response.setBody(healthCheck);Common Use Cases
Automated Change Request Creation from User Stories
Development teams create user stories in Azure DevOps that automatically generate corresponding change requests in ServiceNow when they move to the 'Committed' state. The integration maps story details like acceptance criteria to change request implementation plans and assigns the change to the appropriate approval workflow based on story points or business value. This ensures all development work follows proper change management processes while reducing manual overhead for developers. Business value includes improved compliance, reduced deployment risk, and better traceability between business requirements and technical changes.
Pipeline Deployment Approval Gates
Release pipelines in Azure DevOps include approval gates that query ServiceNow change requests before deploying to production environments. The gate polls a ServiceNow REST endpoint every few minutes, checking if the associated change request has received all required approvals and is in the 'Implement' state. Failed builds automatically update the change request status to 'On Hold' and notify change managers, while successful deployments trigger automatic change closure. This use case provides governance over production deployments while maintaining automated CI/CD pipeline efficiency.
Git Commit Traceability to Change Records
Developers include change request numbers in their Git commit messages, enabling automatic linking between code changes and change management records. A scheduled job parses recent commits from Azure DevOps repositories, extracts change numbers using regex patterns, and creates relationship records in ServiceNow. Change managers can view all commits associated with a change request through a custom related list, providing complete audit trails for compliance and post-implementation reviews. This delivers end-to-end traceability from business requirement through development to deployment.
Build Failure Impact Analysis
When builds fail in Azure DevOps pipelines, the integration automatically identifies affected change requests and updates their risk assessments based on the failure impact. The system analyzes which work items are linked to failed builds, updates corresponding change requests with build failure details, and escalates critical changes to emergency approval workflows if production deployments are at risk. Change advisory boards receive automated reports showing build health across all pending changes, enabling data-driven go/no-go decisions for release windows.
Release Notes Synchronization to CMDB
Completed releases in Azure DevOps automatically create or update Configuration Items in the ServiceNow CMDB with version information, deployment dates, and release notes. The integration extracts artifact details from successful releases, maps them to existing CIs based on application names or creates new CIs for net-new deployments. Release notes become part of the CI documentation, and deployment timestamps update CI operational status and version tracking. This maintains accurate CMDB data without manual intervention and provides operations teams with current application version information for incident management.
Troubleshooting
Azure DevOps spoke actions failing with 401 Unauthorized errors
First check if the Personal Access Token has expired by testing it directly in Azure DevOps REST API using a tool like Postman with the same credentials. Navigate to Connections & Credentials > Connection & Credential Aliases and verify the stored PAT is correct and has appropriate scopes (Work Items read/write, Build read, Release read minimum). Check the Integration Hub > Action History for detailed error messages that may indicate specific permission issues. If using Azure AD authentication, ensure the service principal has been granted necessary permissions in the Azure DevOps organization security settings.
Work items syncing to ServiceNow but field mappings not working correctly
Navigate to DevOps > Administration > Tool Configurations and review the field mapping configuration between Azure DevOps and ServiceNow fields. Enable debug logging by setting the log level to 'Debug' for the 'com.sn_azure_devops_spoke' application in System Logs > Log Levels. Check Transform Map logs in System Import Sets > Transform History to see if field transformations are executing correctly and identify any script errors. Verify that target ServiceNow fields exist and are writable by the integration user, as read-only or inactive fields will cause mapping failures silently.
Pipeline approval gates timing out before ServiceNow responds
Check the Scripted REST API execution time by enabling debugging and reviewing System Logs > All for performance bottlenecks in your approval endpoint code. Verify that Azure DevOps gate polling intervals are set appropriately (recommend 5-10 minutes) and timeout values allow sufficient time for manual approvals in ServiceNow workflows. Review the REST API response format to ensure it matches what Azure DevOps expects - the response should include clear boolean values for approval status. Consider implementing caching in the REST API if change request lookups are slow, and ensure database indexes exist on frequently queried fields like change request numbers.
Duplicate change requests being created for the same Azure DevOps work item
Implement proper duplicate detection in your Transform Maps by adding a condition that checks for existing change requests with the same Azure DevOps work item ID before creating new records. Navigate to System Import Sets > Transform Maps and add a 'Coalesce on' field configuration using your custom Azure DevOps ID field to prevent duplicates. Check if multiple scheduled imports or Flow executions are running simultaneously by reviewing System Definition > Scheduled Jobs and Integration Hub > Executions for overlapping runs. Add proper error handling and logging to identify the source of duplicate creation triggers.
CMDB CI updates failing with reference field errors
Verify that all reference fields in the CMDB CI record have valid values by checking the referenced tables and ensuring the records exist. Navigate to Configuration > Tables & Columns and review the CMDB CI table schema to confirm required fields and their data types match what you're sending from Azure DevOps. Use GlideRecord.setDisplayValue() instead of setValue() for reference fields when you have display values rather than sys_ids from Azure DevOps data. Check System Import Sets > Import Log for detailed error messages about field validation failures and ensure your integration user has write access to all CMDB tables being updated.
Integration Hub flows failing with rate limit exceeded errors
Implement exponential backoff retry logic in your flows by adding Wait actions between Azure DevOps API calls and reducing the frequency of scheduled flow executions during peak usage periods. Check the Azure DevOps rate limit headers in the HTTP response to understand current usage and remaining quota - the limit is 10,000 requests per 10 minutes per organization. Consider batching multiple operations into single API calls where possible using Azure DevOps batch APIs, and implement flow controls to prevent simultaneous executions of the same flow. Monitor Integration Hub > Action History to identify which specific actions are hitting rate limits most frequently and optimize those calls first.
Pro Tips
- →Implement custom retry logic with exponential backoff in your Transform Maps and Business Rules when calling Azure DevOps APIs, as the standard spoke actions don't always handle transient network failures gracefully. Use the GlideSystem.sleep() method sparingly and consider queuing failed operations for later retry rather than blocking the current transaction.
- →Create custom dashboard indicators using Performance Analytics to track integration health metrics like sync latency, error rates, and data freshness across Azure DevOps and ServiceNow. Set up automated reports that alert stakeholders when integration SLAs are at risk, such as when change request creation lags behind work item updates by more than 30 minutes.
- →Leverage ServiceNow's Flow Designer subflows to create reusable integration components that can be shared across multiple Azure DevOps projects or organizations. Build parameterized subflows for common operations like 'Update Change Request from Work Item' that accept project-specific mapping configurations as input variables.
- →Implement field-level change detection by storing hash values of critical Azure DevOps fields in ServiceNow and only triggering updates when content actually changes. This reduces unnecessary API calls, prevents workflow noise from redundant updates, and improves overall integration performance while maintaining data accuracy.
- →Use ServiceNow's Metric Base to track integration-specific KPIs like average time from work item creation to change request approval, build success rates by change type, and deployment frequency metrics. Create custom metric definitions that aggregate data across both platforms to provide unified DevOps insights to management teams.
- →Configure Connection & Credential Alias rotation policies to automatically refresh Azure DevOps Personal Access Tokens before they expire, using ServiceNow's credential lifecycle management features combined with Azure AD service principals for enterprise-grade security and reduced maintenance overhead.
Known Limitations
- —Azure DevOps REST API enforces a rate limit of 10,000 requests per 10 minutes per organization, which can become a bottleneck for large-scale integrations with frequent synchronization requirements. The ServiceNow spoke includes basic throttling but doesn't provide sophisticated queuing or prioritization mechanisms for high-volume scenarios.
- —Complex Azure DevOps work item hierarchies with multiple levels of parent-child relationships cannot be directly mapped to ServiceNow's change request structure without custom flattening logic. The integration doesn't automatically maintain hierarchical relationships, requiring additional development for organizations that rely heavily on epic-feature-story structures.
- —Real-time webhook integration from Azure DevOps to ServiceNow requires custom development as the official spoke doesn't include webhook handlers. Organizations must implement Scripted REST APIs and configure Azure DevOps service hooks manually, adding complexity and maintenance overhead compared to polling-based synchronization.
- —The Azure DevOps spoke doesn't support Test Plans or Test Suites synchronization natively, limiting integration capabilities for organizations that manage test cases and test execution tracking through Azure DevOps. Custom REST message implementations are required to access testing APIs and sync test results to ServiceNow.
- —Cross-organization Azure DevOps integration requires separate connection configurations for each organization, and the spoke doesn't provide consolidated management capabilities for multi-tenant scenarios. Large enterprises with multiple Azure DevOps organizations must duplicate configuration and monitoring across each integration instance.
Frequently Asked Questions
Can I integrate with both Azure DevOps Server on-premises and Azure DevOps Services simultaneously?
Yes, you can configure multiple tool configurations in ServiceNow to connect to different Azure DevOps instances, but each requires its own Connection & Credential Alias and separate spoke configurations. On-premises Azure DevOps Server connections require a MID Server to handle the network connectivity, while Azure DevOps Services connections work directly through ServiceNow's cloud infrastructure. You'll need to manage separate authentication credentials and may encounter different API version capabilities between cloud and on-premises instances.
How do I handle Azure DevOps organizations with custom work item types that don't map to standard ServiceNow change request types?
Create custom change request categories or use ServiceNow's Task table extensions to accommodate Azure DevOps custom work item types through the DevOps tool configuration mapping interface. You can extend the change request table with custom fields that mirror your Azure DevOps custom fields, or implement Transform Map scripts that convert custom work item types to appropriate ServiceNow record types. Consider using ServiceNow's Customer Service Management or Project Management applications if your custom work items align better with those data models than change management.
What happens to ServiceNow change requests when the linked Azure DevOps work item is permanently deleted?
ServiceNow change requests remain intact when linked Azure DevOps work items are deleted, but subsequent synchronization attempts will fail with 'work item not found' errors. Implement error handling in your integration flows to detect deleted work items and either mark the change request with a specific state or add work notes indicating the source work item is no longer available. You can create scheduled cleanup jobs that identify orphaned change requests and either close them automatically or flag them for manual review by change managers.
Can I use the Azure DevOps integration to trigger ServiceNow workflows beyond just change management?
Absolutely, the Azure DevOps spoke actions can be used in any Integration Hub flow or called from Business Rules to trigger various ServiceNow workflows including Incident Management for build failures, Problem Management for recurring deployment issues, or Project Management for release planning. You can create custom flows that respond to Azure DevOps events and interact with any ServiceNow application, such as automatically creating incidents when production builds fail or updating project tasks when releases complete. The spoke provides building blocks that can be combined with ServiceNow's workflow capabilities across the entire platform.
How do I sync Azure DevOps branch policies and pull request approvals with ServiceNow approval workflows?
While the standard Azure DevOps spoke doesn't include pull request management actions, you can implement custom REST Message calls to the Azure DevOps Git Pull Request API to retrieve approval status and sync it with ServiceNow approval workflows. Create Scripted REST APIs in ServiceNow that Azure DevOps can call via webhooks when pull request status changes, then trigger appropriate ServiceNow workflow transitions based on the approval state. Consider using ServiceNow's Approval Engine to create parallel approval processes that mirror your Azure DevOps branch protection policies.
What's the best practice for handling Azure DevOps Personal Access Token expiration in production environments?
Implement Azure Active Directory service principals with client credentials flow instead of Personal Access Tokens for production integrations, as these don't expire and provide better security governance through Azure AD. If you must use PATs, create calendar reminders before expiration dates and implement monitoring that tests token validity daily through health check flows. Store backup tokens with the same permissions and implement automated failover logic that switches to backup credentials when primary tokens fail, while sending alerts to administrators about impending expirations.
Can I use this integration to automatically deploy ServiceNow applications based on Azure DevOps releases?
Yes, you can extend the integration to trigger ServiceNow application deployments by creating Flow Designer flows that monitor Azure DevOps releases and call ServiceNow's Application Repository APIs for automated deployments. Use the Azure DevOps 'Get Releases' spoke action to detect successful releases, then implement conditional logic that downloads application files from Azure DevOps artifacts and uploads them to ServiceNow using the Import Set API or App Engine Studio deployment APIs. However, this requires careful consideration of ServiceNow's deployment best practices, update set dependencies, and proper testing in sub-production environments before automating production deployments.
Test Your Knowledge
Quick 3-question quiz — see how your ServiceNow skills stack up.
A list view on a table with millions of records is slow. Best fix?
Select an answer to continue