Skip to content

Automated Device Classification

After a discovery scan, devices with status Not Imported need to be onboarded into Nautobot. The onboarding form requires a Location, a Role, and optionally a Tenant — fields that would otherwise have to be filled in manually for every device.

Classification is fully automatic. There is no separate job to run and no button to press — results are recomputed in the background whenever a discovery scan completes or a rule is created, edited, or deleted.

When Classification Is Useful

Use classification when device hostnames, identifiers, or IP scopes follow predictable naming conventions that map to existing Nautobot Locations, Roles, or Tenants. Typical examples include site codes embedded in hostnames (ams-, nyc-), role keywords (-core-, -edge-, -access-), or per-tenant subnet ranges.

Skip classification (or leave it disabled with no rules defined) if your environment has no consistent naming convention, if hostnames are arbitrary, or if you prefer to assign Location, Role, and Tenant manually during onboarding for every device.

How It Works

A DeviceClassificationRule describes how to derive a single classification target — Location, Role, or Tenant — from a discovered device. Rules are grouped by target and evaluated in weight order (ascending, then by name). For each target, the first enabled rule that produces a single unambiguous match wins. The three targets are evaluated independently, so a device can end up with a Location classified but not a Role.

For every Not Imported device the engine performs the following lookup for each target:

  1. If the rule has an IP Scope defined, the device's IP must fall within one of the listed prefixes. Otherwise the rule is skipped.
  2. The configured Source Field is read from the device (currently hostname).
  3. The Source Pattern is applied as a regex. The pattern must contain a named capture group (?P<value>...) — the captured substring is the Extracted Value.
  4. The optional Extracted Value Transformation is applied (e.g., lowercase).
  5. The Match Against model is queried using {match_field}__{match_operator}=extracted_value, narrowed by any additional Match Filters constraints.
  6. If exactly one object is returned, it is recorded as the match together with the rule that produced it. Zero or multiple matches are skipped and the next rule in the target's set is tried.

Results are written to a DiscoveredDeviceClassification record attached to the discovered device.

Tip

Classification only ever fires when a lookup returns exactly one candidate. Zero or multiple matches are intentionally treated as no match — incorrect auto-assignment is more harmful than no assignment.

Configuring Rules

Navigate to Devices > Discovery > Classification Rules > + Add.

The full field reference is documented under the Classification Rule data model. The most commonly used fields are:

Field Purpose
Classify As Which device field this rule populates: Location, Role, or Tenant.
Weight Lower weight = higher priority. The first matching enabled rule in each target set wins.
Source Pattern Regex with a named (?P<value>...) capture group. The captured substring is the value used in the lookup.
Match Against The Nautobot model the value is matched against — must be Location, Role, or Tenant.
Match Operator How the extracted value is compared to the Match Field (e.g., iexact, icontains).
Match Filters Extra equality filters that narrow the lookup, e.g. {"status__name": "Active"}. Up to two foreign-key traversals are supported.
IP Scope Optional list of prefixes restricting the rule to a subset of devices.

Note

Classify As and Match Against must be compatible: Location ↔ dcim.location, Role ↔ extras.role, Tenant ↔ tenancy.tenant. Mismatched combinations are rejected at save time.

Examples

Classify Location from a site code in hostnames

Hostnames follow <site>-<role>-<seq>, e.g., ams-core-01, nyc-edge-02. The site codes (ams, nyc) match Location names in Nautobot.

Field Value
Name Classify location from hostname site code
Weight 10
Classify As Location
Source Pattern ^(?P<value>[a-z]{2,4})-
Match Against dcim \| location
Match Field name
Match Operator exact

ams-core-01 extracts ams, finds one matching Location, and is classified as Amsterdam. xyz-sw-01 extracts xyz, finds no match, and the rule is skipped.

Classify Role from a hostname segment

Hostnames embed a role keyword: nyc-core-01, lon-edge-03, par-access-02.

Field Value
Name Classify role from hostname
Weight 10
Classify As Role
Source Pattern -(?P<value>core\|edge\|access)-
Match Against extras \| role
Match Field name
Match Operator iexact

Classify Tenant by IP scope

Different tenants own different subnets. Devices in 10.50.0.0/16 belong to Tenant A; devices in 172.20.0.0/14 belong to Tenant B. Two rules with the same weight but different ip_scope values ensure only the right rule fires per subnet:

Field Rule A Rule B
Classify As Tenant Tenant
IP Scope 10.50.0.0/16 172.20.0.0/14
Source Pattern ^(?P<value>tena)- ^(?P<value>tenb)-
Match Against tenancy \| tenant tenancy \| tenant
Match Operator icontains icontains

Fallback rules with increasing weight

To support multiple conventions with a fallback, set lower weights on the more specific rules. The engine stops at the first rule that returns exactly one match.

Weight Pattern Notes
10 ^(?P<value>[a-z]{3})- 3-letter site code (precise)
50 ^(?P<value>[a-z]{2})- 2-letter site code (fallback)
100 ^(?P<value>[a-z]{4})- 4-letter site code (last resort)

Viewing Classification Results

Open any Not Imported discovered device — the Automated Classification panel on the detail view shows the pre-computed Location, Role, and Tenant matches. The panel only renders when at least one of the three targets has been classified; devices with no matches will not show it.

The rule that produced each match and a human-readable reason — for example, Rule "Classify location from hostname site code": extracted "ams" from 'hostname' — matched location name="ams" — are stored on the DiscoveredDeviceClassification record and accessible via the REST API and GraphQL, but are not displayed in the UI panel.

Caveats and Limitations

Only Not Imported devices are classified. As soon as a device transitions to any other status (Imported, Partially Imported, Conflict), its classification record is deleted automatically.

The current version supports hostname as the only Source Field. Devices with a blank hostname are skipped by every rule that inspects hostname.

Classification does not modify devices, change inventory status, or start onboarding. It only writes suggestions to DiscoveredDeviceClassification. Onboarding remains a deliberate human action.

Recomputation is whole-set: every change to a rule (create, edit, disable, delete) re-evaluates all Not Imported devices against all current rules. Classification results therefore stay consistent with the latest rule set and the latest Nautobot Location, Role, and Tenant data.

The match_filters JSON dict accepts Django ORM field lookups but is limited to two foreign-key traversals (e.g., parent__location_type__name is allowed; deeper paths are rejected at save time). The source_pattern field must contain a (?P<value>...) named capture group; a pattern without it is rejected at save time.

What's Next?