Skip to main content

NetBox Device Type Converter

Skill: infrahub-converting-netbox-device-types

The NetBox Device Type Converter turns NetBox device-type and module-type YAML into Infrahub Object Templates, so you create a device with its ports already in place from one reusable definition. The input format is netbox-community/devicetype-library, which you can browse at the NetBox Data Exchange, and a second bundled script produces that same format from a running NetBox instance, so the catalogue you already maintain is a valid input too. A bundled Python script does the conversion, driven by a mapping profile that describes your target schema. Point it at the target schema and read what it reports back. It does not edit your schema for you, and it does not guess a field name the profile does not define.

When to use​

  • Seeding a new Infrahub instance with vendor device models from the NetBox library
  • Exporting the device types someone actually runs, out of their own NetBox instance, and converting those
  • Converting a few device types for a specific project or lab topology
  • Re-running a conversion after the upstream library or your local schema changed
  • Building the mapping profile that binds NetBox fields to a custom Infrahub schema

A one-off export from a running NetBox is in scope: a bundled script reads the instance over its REST API and writes the library file format, which the converter then takes unchanged. What is out of scope is continuous two-way replication between the two systems, which is infrahub-sync, a separate product. The export here is a snapshot into files, not a sync.

What it produces​

One NetBox file becomes several Infrahub artifacts, because Infrahub splits what NetBox keeps together:

NetBoxInfrahubWhy
manufacturer: CiscoOrganizationManufacturer objectManufacturers are first-class objects
model, part_number, u_height, weightDcimDeviceType objectTemplates hold no model data
interfaces: and other component listsTemplateDcimDevice plus component templatesThe reusable blueprint
module-types/*.yamlDcimModuleType object, optionally a module templateA second input family, told apart by the absence of a slug

The files are numbered in dependency order, so loading them in sequence satisfies each file's references:

  • 01_manufacturers.yml
  • 02_device_types.yml
  • 03_device_templates.yml
  • 04_module_types.yml
  • 05_module_templates.yml

Empty files are not written, so a device-types-only run produces only the first three.

A Markdown coverage report names everything the profile could not map. It is written to the --report path, which is resolved on its own rather than inside the output directory, and defaults to coverage-report.md in the current directory.

Example prompts​

  • "Convert these Cisco device types into Infrahub object templates"
  • "Pull the device types out of our NetBox and turn them into object templates"
  • "Seed my instance with device models from the NetBox devicetype-library"
  • "Build a mapping profile for my custom DCIM schema"
  • "Re-run the device-type conversion, we upgraded schema-library"
  • "Convert the module types too, including the line cards"

Key rules enforced​

  • generate_template: true comes first: Template* kinds exist only where a node declares it, so the skill checks the target schema rather than assuming either way; this is the most common reason a conversion loads nothing
  • Names come from the profile, never guessed: every Infrahub kind, attribute, and relationship name is read from a YAML mapping profile, so a custom schema needs a new profile rather than a forked script
  • Competing fields declare precedence: NetBox defines more free-text fields than most schemas have room for, so the profile names which field falls back to which; the loser is reported as shadowed, and an undeclared collision is refused rather than letting mapping order decide it silently
  • Shared relationships accumulate: where two NetBox component lists map to the same Infrahub relationship, both are kept; assigning rather than accumulating would silently erase the first list
  • Integers only: Infrahub has no float or decimal attribute kind, so every numeric transform emits a whole number
  • Nothing is dropped silently: anything the profile cannot map is skipped and named in the coverage report, which closes with an explanation of why each gap exists
  • Template names are slug-based and parent-namespaced: names stay unique across the whole library rather than colliding between vendors
  • The skill offers schema changes; it does not make them: enabling generate_template is a migration against your source of truth, so it is proposed for you to apply

Common mistakes it catches​

MistakeWhat the skill does instead
Assuming Template* kinds already existChecks the target schema for generate_template: true before converting
Hand-transcribing a 48-port switchRuns the script, which is exact and repeatable across thousands of device types
Editing the script for a custom schemaWrites a new mapping profile, leaving the script untouched
Reading a clean run as a lossless onePoints you at the coverage report, which names what did not convert
Loading the output files in arbitrary orderNumbers them 01–05 in dependency order
Expecting {module} port names to resolveExplains that the bay position is known only once a module is installed
Reaching for this to sync a live NetBoxSends you to infrahub-sync, which is a different product

Exporting from a running NetBox​

When the device types live in your own instance rather than in the published library, a second bundled script fetches them and writes the same file format, so the two steps chain without a conversion in between. It needs pynetbox 7.0 or later, PyYAML, and a read-only API token.

pip install 'pynetbox>=7.0' pyyaml
SKILL=/path/to/infrahub-converting-netbox-device-types
export NETBOX_TOKEN=...
python "$SKILL/scripts/netbox_export_device_types.py" \
--url https://netbox.example.com \
--in-use \
--module-types \
--output-dir ./netbox-export

--in-use keeps only device types with at least one device and module types with at least one module, going by the counts NetBox reports rather than by rack placement. On a real instance that is a much smaller and more relevant set than the whole catalogue. --manufacturer narrows both further; --slug narrows device types only, since module types have no slug.

The export closes with its own report, in the same spirit as the coverage report: fields NetBox holds that the library format cannot carry, fields NetBox left unset that the library format requires, component endpoints absent from that NetBox version, file names that collided after sanitising, and whether the instance predates NetBox 4.5, whose front-port mapping shape differs. Read it before converting.

This is a one-way snapshot into files. Continuous replication in both directions is infrahub-sync.

Running it​

The skill normally runs the converter for you. To run it manually, set SKILL to wherever your installation put the skill directory and stay in your own working directory. The manual copy puts it under your project root; the npx installer and the Claude Code plugin place it elsewhere, under a cache that reinstalling wipes, so the outputs below are deliberately relative to you rather than to the skill.

SKILL=/path/to/infrahub-converting-netbox-device-types

python "$SKILL/scripts/netbox_to_infrahub_templates.py" \
devicetype-library/device-types/Cisco/ \
--mapping "$SKILL/scripts/mappings/schema-library.yml" \
--output-dir ./generated \
--report ./generated/coverage-report.md

Point it at a single file, a folder, or a mixed tree of device types and module types; the two families are told apart automatically, so a mixed tree converts in one pass. The skill includes four mapping profiles: schema-library.yml for device types, schema-library-modules.yml for module types as well, schema-library-module-ports.yml to carry each module's ports as declarations, from which the bundled generator creates device interfaces for the interface ports, and an annotated _template.yml to copy for a custom schema. The converter refuses _template.yml until its placeholder kinds are replaced, and refuses two device types that share a model, because loading both would overwrite one with the other.

warning

Read the coverage report before loading anything. Against the stock schema-library.yml profile most NetBox component lists have no equivalent node, so a report full of unmapped entries is the normal path rather than an error: it is the list of schema changes a lossless conversion would need.

tip

Module port names contain NetBox's {module} token, which no conversion can resolve, because the bay position is known only once a module is installed. With the schema-library module extensions loaded, generate_template: true added to DcimModule, and the schema-library-module-ports.yml profile, each module template carries its ports as declarations, and a bundled generator resolves the token per installed module and creates the real device interfaces. Only interface ports become interfaces: console ports need a console interface kind in the schema, and power ports stay declarations.