CI Relationship Mapping
SkillDev toolsCI relationship management including creation, validation, dependency analysis, and orphan detection
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the CI Relationship Mapping skill
What this skill tells your AI
The instructions your AI receives, as published by happy-technologies-llc/happy-platform-skills in skills/cmdb/relationship-mapping/SKILL.md and read by ahel’s review.
Overview
CI relationships form the backbone of CMDB value. Without relationships, CIs are isolated islands of data. This skill covers:
- Understanding relationship types and their semantics
- Creating and validating relationships between CIs
- Analyzing dependency chains for impact assessment
- Detecting orphan CIs that lack relationships
- Maintaining relationship health over time
When to use: When modeling service dependencies, preparing for change impact analysis, auditing CMDB completeness, or troubleshooting service outages.
Value proposition: Well-mapped relationships enable accurate impact analysis, reducing change failures by up to 50% and decreasing MTTR during incidents.
Prerequisites
- Roles:
cmdb_adminoritilwith CMDB write access - Access: cmdb_rel_ci, cmdb_rel_type, cmdb_ci tables
- Knowledge: CI class hierarchy, dependency modeling concepts
- Related skills: Complete
cmdb/ci-discoveryfirst
Procedure
Step 1: Understand Relationship Types
ServiceNow provides relationship types in cmdb_rel_type. Each relationship has:
- Parent descriptor: How the parent relates to the child
- Child descriptor: How the child relates to the parent
Common Relationship Types:
| Relationship | Parent Descriptor | Child Descriptor | Use Case |
|---|---|---|---|
| Runs on | Runs on | Hosts | Application on Server |
| Depends on | Depends on | Used by | Service dependencies |
| Contains | Contains | Contained by | Physical containment |
| Connects to | Connects to | Connected by | Network connectivity |
| Sends data to | Sends data to | Receives data from | Data flows |
| Cluster of | Cluster of | Cluster member | Clusters |
| Uses | Uses | Is used by | Generic dependency |
Query available relationship types:
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_type
query: active=true
fields: sys_id,name,parent_descriptor,child_descriptor
limit: 100
REST API:
GET /api/now/table/cmdb_rel_type?sysparm_query=active=true&sysparm_fields=sys_id,name,parent_descriptor,child_descriptor&sysparm_limit=100
Step 2: Query Existing Relationships
Before creating relationships, understand what exists:
Find all relationships for a CI:
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_ci
query: parent=[ci_sys_id]^ORchild=[ci_sys_id]
fields: parent,child,type,sys_created_on
limit: 50
Find downstream dependencies (what depends on this CI):
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_ci
query: child=[ci_sys_id]^type.parent_descriptorLIKEDepends
fields: parent,parent.name,type,type.parent_descriptor
Find upstream dependencies (what this CI depends on):
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_ci
query: parent=[ci_sys_id]^type.parent_descriptorLIKEDepends
fields: child,child.name,type,type.child_descriptor
Step 3: Create Relationships
Determine the correct relationship type first:
Decision Matrix:
| Parent CI Type | Child CI Type | Recommended Relationship |
|---|---|---|
| Application | Server | Runs on |
| Business Service | Application | Depends on |
| Server | Rack | Contained by |
| Server | Server | Connects to (if network) |
| Database | Server | Runs on |
| Load Balancer | Server Pool | Contains |
Find relationship type sys_id:
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_type
query: nameLIKERuns on::Runs on
fields: sys_id,name,parent_descriptor,child_descriptor
Create the relationship:
Tool: SN-Create-Record
Parameters:
table_name: cmdb_rel_ci
data:
parent: [parent_ci_sys_id]
child: [child_ci_sys_id]
type: [relationship_type_sys_id]
Example - Application runs on Server:
Tool: SN-Create-Record
Parameters:
table_name: cmdb_rel_ci
data:
parent: "abc123..." # Application CI sys_id
child: "def456..." # Server CI sys_id
type: "55c95bf6c0a8010e0118ec7056e1c57d" # Runs on::Hosts
Step 4: Validate Relationships
Check for invalid relationships:
Find relationships with missing CIs:
Tool: SN-Execute-Background-Script
Parameters:
description: Find invalid relationships with missing CIs
script: |
var gr = new GlideRecord('cmdb_rel_ci');
gr.addQuery('parent.sys_idISEMPTY^ORchild.sys_idISEMPTY');
gr.query();
gs.info('Invalid relationships found: ' + gr.getRowCount());
while (gr.next()) {
gs.info('Invalid rel: ' + gr.sys_id + ' parent=' + gr.parent + ' child=' + gr.child);
}
Find duplicate relationships:
Tool: SN-Execute-Background-Script
Parameters:
description: Detect duplicate relationships
script: |
var duplicates = new GlideAggregate('cmdb_rel_ci');
duplicates.addAggregate('COUNT');
duplicates.groupBy('parent');
duplicates.groupBy('child');
duplicates.groupBy('type');
duplicates.addHaving('COUNT', '>', 1);
duplicates.query();
gs.info('Duplicate relationship combinations found: ' + duplicates.getRowCount());
while (duplicates.next()) {
gs.info('Duplicate: parent=' + duplicates.parent + ' child=' + duplicates.child + ' type=' + duplicates.type + ' count=' + duplicates.getAggregate('COUNT'));
}
Validate relationship type appropriateness:
Some relationship types are only valid for certain CI classes. Check the relationship type's parent_ci_class and child_ci_class fields if populated.
Step 5: Analyze Dependency Chains
Understanding full dependency chains is critical for impact analysis.
Get complete dependency tree (recursive):
Tool: SN-Execute-Background-Script
Parameters:
description: Build dependency tree for CI
script: |
var ciSysId = 'YOUR_CI_SYS_ID';
var maxDepth = 5;
var visited = {};
var tree = [];
function getDependencies(parentId, depth, direction) {
if (depth > maxDepth || visited[parentId]) return;
visited[parentId] = true;
var gr = new GlideRecord('cmdb_rel_ci');
if (direction === 'down') {
gr.addQuery('child', parentId);
gr.addQuery('type.parent_descriptor', 'CONTAINS', 'Depends');
} else {
gr.addQuery('parent', parentId);
gr.addQuery('type.parent_descriptor', 'CONTAINS', 'Depends');
}
gr.query();
while (gr.next()) {
var targetId = direction === 'down' ? gr.parent.toString() : gr.child.toString();
var targetName = direction === 'down' ? gr.parent.name.toString() : gr.child.name.toString();
tree.push({
depth: depth,
direction: direction,
ci_name: targetName,
ci_sys_id: targetId
});
getDependencies(targetId, depth + 1, direction);
}
}
getDependencies(ciSysId, 1, 'down');
gs.info('Upstream dependencies (what depends on this CI):');
tree.forEach(function(item) {
gs.info(' '.repeat(item.depth) + item.ci_name);
});
Identify critical path:
Services with single points of failure have critical paths:
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_ci
query: parent.sys_class_name=cmdb_ci_service^type.parent_descriptorLIKEDepends
fields: parent.name,child.name,child.sys_class_name
Step 6: Detect Orphan CIs
Orphan CIs (those without relationships) reduce CMDB value and complicate impact analysis.
Find CIs with no relationships:
Tool: SN-Execute-Background-Script
Parameters:
description: Find orphan CIs with no relationships
script: |
var orphans = [];
var ciClasses = ['cmdb_ci_server', 'cmdb_ci_appl', 'cmdb_ci_database_instance'];
ciClasses.forEach(function(ciClass) {
var gr = new GlideRecord(ciClass);
gr.addQuery('operational_status', '1');
gr.query();
while (gr.next()) {
var relGr = new GlideRecord('cmdb_rel_ci');
relGr.addQuery('parent', gr.sys_id);
relGr.addOrCondition('child', gr.sys_id);
relGr.setLimit(1);
relGr.query();
if (!relGr.hasNext()) {
orphans.push({
sys_id: gr.sys_id.toString(),
name: gr.name.toString(),
class: ciClass
});
}
}
});
gs.info('Orphan CIs found: ' + orphans.length);
orphans.forEach(function(o) {
gs.info(' ' + o.class + ': ' + o.name + ' (' + o.sys_id + ')');
});
MCP Alternative - Query-based approach:
Tool: SN-Query-Table
Parameters:
table_name: cmdb_ci_server
query: operational_status=1^sys_idNOT IN(SELECT parent FROM cmdb_rel_ci)^sys_idNOT IN(SELECT child FROM cmdb_rel_ci)
fields: name,ip_address,sys_class_name
limit: 50
Note: Complex subqueries may not work via REST API. Use background script for reliability.
Step 7: Maintain Relationship Health
Periodic cleanup script:
Tool: SN-Execute-Background-Script
Parameters:
description: Clean up invalid relationships
script: |
var deleted = 0;
// Delete relationships where parent CI was deleted
var gr = new GlideRecord('cmdb_rel_ci');
gr.addNullQuery('parent');
gr.query();
while (gr.next()) {
gr.deleteRecord();
deleted++;
}
// Delete relationships where child CI was deleted
gr = new GlideRecord('cmdb_rel_ci');
gr.addNullQuery('child');
gr.query();
while (gr.next()) {
gr.deleteRecord();
deleted++;
}
gs.info('Deleted ' + deleted + ' invalid relationships');
Update stale relationships: When a CI's operational status changes, relationships may need updates:
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_ci
query: parent.operational_status!=1^ORchild.operational_status!=1
fields: sys_id,parent.name,child.name,parent.operational_status,child.operational_status
Tool Usage Summary
| Operation | MCP Tool | REST Endpoint |
|---|---|---|
| List relationship types | SN-Query-Table | GET /cmdb_rel_type |
| Query relationships | SN-Query-Table | GET /cmdb_rel_ci |
| Create relationship | SN-Create-Record | POST /cmdb_rel_ci |
| Delete relationship | SN-Update-Record (set inactive) | DELETE /cmdb_rel_ci/{id} |
| Complex queries | SN-Execute-Background-Script | POST /api/sn_chg_rest/change |
| CI relationships API | N/A | GET /cmdb/instance/{id}/relation |
Best Practices
- Bidirectional Awareness: Remember relationships have two perspectives (parent/child)
- Minimum Relationships: Every operational CI should have at least one relationship
- Type Consistency: Use consistent relationship types across similar CI patterns
- Avoid Circular Dependencies: A should not depend on B if B depends on A
- Document Business Context: Use relationship attributes to explain why the relationship exists
- Regular Audits: Run orphan detection monthly; invalid relationship cleanup weekly
- Discovery Integration: Align manual relationships with discovery-created relationships
Troubleshooting
Relationship Not Showing in Dependency View
Symptom: Created relationship doesn't appear in CI dependency views
Cause: Relationship type not configured for dependency visualization
Solution: Check cmdb_rel_type record - ensure is_used_by and is_dependency flags are set appropriately
Duplicate Relationships After Discovery
Symptom: Same relationship exists multiple times Cause: Manual creation overlapped with discovery Solution: Run duplicate detection script; delete duplicates keeping discovery-created records
Circular Dependency Detected
Symptom: Impact analysis shows infinite loop warning Cause: CI A depends on B, B depends on C, C depends on A Solution: Review and break the circular chain; often indicates incorrect relationship type usage
Relationship Type Not Found
Symptom: Cannot find appropriate relationship type for use case
Cause: OOB types may not cover all scenarios
Solution: Create custom relationship type via cmdb_rel_type table (requires cmdb_admin)
Examples
Example 1: Map a Three-Tier Application
# 1. Identify the CIs
Business Service: "Customer Portal"
Web Application: "Portal Frontend"
App Server: "prod-app-01"
Database: "Portal DB"
DB Server: "prod-db-01"
# 2. Find relationship type sys_ids
Tool: SN-Query-Table
Parameters:
table_name: cmdb_rel_type
query: nameLIKEDepends on^ORnameLIKERuns on
fields: sys_id,name,parent_descriptor
# 3. Create relationships (batch in one message)
# Service depends on Web App
SN-Create-Record: cmdb_rel_ci
parent: [service_sys_id], child: [webapp_sys_id], type: [depends_on_type]
# Web App runs on App Server
SN-Create-Record: cmdb_rel_ci
parent: [webapp_sys_id], child: [appserver_sys_id], type: [runs_on_type]
# Web App depends on Database
SN-Create-Record: cmdb_rel_ci
parent: [webapp_sys_id], child: [database_sys_id], type: [depends_on_type]
# Database runs on DB Server
SN-Create-Record: cmdb_rel_ci
parent: [database_sys_id], child: [dbserver_sys_id], type: [runs_on_type]
Example 2: Orphan Detection and Remediation
# 1. Find orphan servers
Tool: SN-Execute-Background-Script
Parameters:
script: [orphan detection script from Step 6]
# 2. For each orphan, determine what it hosts
Tool: SN-Query-Table
Parameters:
table_name: cmdb_ci_appl
query: install_dateLIKE[orphan_ip_address]
fields: name,sys_id
# 3. Create missing relationships
Tool: SN-Create-Record
Parameters:
table_name: cmdb_rel_ci
data:
parent: [app_sys_id]
child: [orphan_server_sys_id]
type: [runs_on_type_sys_id]
Related Skills
cmdb/ci-discovery- CI creation and classificationcmdb/impact-analysis- Using relationships for impact analysiscmdb/data-quality- CMDB data quality managementitsm/change-management- Changes and CI relationships
References
Signals
- GitHub stars
- 37
- Forks
- 13
- Last commit
- Jul 2026
Advanced
- Catalog kind
- skill
- Gateway key
relationship-mapping- Source
- github.com/happy-technologies-llc/happy-platform-skills