Unintended SQL Instances and DBs showing up on Tag-Based Service Maps -- Traversal rule issue?

Bobby Campbell
Mega Sage

When tagging infrastructure CIs to application services, the app owner usually gives us a list of servers and databases to be tagged. Once the service recalculates, that app service often shows relationship to SQL instances and databases that we didn't tag and don't necessarily support the specific application.  I'm trying to understand:

 

1) Regarding databases, what is the correct CI level to tag: database, database instance, or server?

2) Assuming we are tagging a shared server that runs an application AND happens to also host a SQL instance, how do we prevent that unrelated SQL instance from showing up as part of the application's map?  If we tag the server, it's pulling in the SQL instance.

 

We have a traversal rule that I think MAY be contributing to the issue: 

Screenshot 2026-07-17 at 3.27.40 PM.png

This is one of those things that might be best figured out by deactivating the rule in sub prod and seeing what happens. But I'm hoping someone else has already been through this and can help.

3 REPLIES 3

Vikram Reddy
Tera Guru

Hi @B​obby Campbell,

 

Neither Service Mapping nor that traversal rule is misbehaving here, it's the tagging level that's exposing you to this.

On question 1: tag at the Database CI (cmdb_ci_database), not the Database Instance and not the server. A database instance or a shared box can host a dozen unrelated databases, so tagging anything above the database itself drags every sibling database along for the ride. Tagging the specific database CI keeps the relationship narrow. That's not spelled out cleanly anywhere in the official docs, but it lines up with how tag-based traversal actually walks the CMDB, and it's the same pattern other admins have landed on when they hit this exact shared-instance problem.

On question 2, here's the actual mechanism. Tag-based Service Mapping treats every tagged CI as a traversal root and walks relationships outward from it, and per ServiceNow's own docs on this feature, "Service Mapping includes CIs that are part of CI relationships even if these CIs do not have tags assigned to them." So when the Application CI is tagged, your rule (Parent Type cmdb_ci_appl, relationship type Runs on::Runs, reversed, order 200) correctly pulls in the Hardware it runs on, that part is doing exactly what it should. The trouble starts the moment you also tag the shared server itself. That makes the server its own traversal root, and any other active rule with Parent Type = Hardware now fires independently off it, walking every relationship that server has, including whatever links it to that unrelated SQL Server instance. That rule in your screenshot isn't the one to chase, it's the App-to-Hardware rule and it's fine. Go look in the Traversal Rules list (svc_traversal_rules) for a rule with Parent Type Hardware or your specific server class, related to Database or Database Instance, Used By = Service by Tags, and Active checked. That's the one that only fires once the server becomes a root. You can flip Active off in sub-prod to confirm it, but the cleaner fix is to just stop tagging the shared server directly: tag the Application and the specific Database CI, and let the existing Runs on relationship bring the correct hardware into the map on its own without ever making it a root.

References

 

Thank you,
Vikram Karety
Octigo Solutions INC

Bobby Campbell
Mega Sage

Thank you. I understand SQL Instance Contains SQL Databases. But why is the SQL Instance the Parent to the Database? In our environment, SQL instances are the parent in both relationships:

 

- SQL Instance is the parent to Windows Server

- SQL Instance is the parent to SQL Database

 

How can this be correct?

Vikram Reddy
Tera Guru

Hi @B​obby Campbell,

 

Stop tagging the shared server itself, that's what's turning it into its own traversal root and dragging the unrelated SQL instance along with it.

Here's the mechanism. Tag-based Service Mapping treats every tagged CI as an entry point, and traversal rules fire independently off each one of those entry points, following a direct, single-hop relationship out to the target class. The target CI doesn't need to be tagged itself to end up in the map, it just needs a direct relationship to something that is tagged. So when only the Application CI is tagged, the rule in your screenshot (Parent Type cmdb_ci_appl, Relationship Type Runs on::Runs, reversed, order 200, Used By Service by Tags) is doing exactly what it should: walking from the app out to the Hardware it runs on. That rule is fine, leave it alone. The problem starts the moment you also tag the server itself. That makes the server a root in its own right, and any other active rule whose Parent Type is Hardware (or your server's specific class) now fires off it independently, walking every direct relationship that box has, including whatever links it to the SQL instance and its databases.

Before you touch the rule you posted, go check these instead:

  • Traversal Rules list: filter svc_traversal_rules for Parent Type Hardware (or your exact server class), Used By Service by Tags, Active true, with a Child Type of Database Instance or Database. That's almost certainly the rule doing the damage, not the app-to-hardware one in your screenshot.
  • Tag candidates: check the Tag-Based Service Family's candidate list to confirm whether the server CI itself is carrying the app's tag, versus only the Application CI carrying it.
  • Direct relationship: confirm there's an actual direct relationship between the Hardware CI and the SQL instance or database CI. Traversal rules can't hop through an intermediate CI, so if the instance is showing up, that relationship exists on the shared box whether you tagged it or not.

Flipping that rule inactive in sub-prod will confirm the theory, but the durable fix is to stop making the server a tagged root at all. Tag the Application CI and let Runs on::Runs bring in the right Hardware on its own, don't tag the Hardware separately unless you actually want it to act as its own entry point into unrelated relationships.

On question 1: tag at the Database CI (cmdb_ci_database), not the Database Instance (cmdb_ci_db_instance) and not the server. An instance is a shared container, one SQL instance can host a dozen unrelated databases for a dozen unrelated apps, so tagging the instance (or the box underneath it) pulls every sibling database along for the ride. Tagging the specific Database CI keeps the traversal scoped to only what that app actually uses, and it lines up with the general CMDB pattern of Database sitting as the logical, app-facing layer above the Database Instance and the physical server underneath it.

 

Thank you,
Vikram Karety
Octigo Solutions INC