Docs
Concepts

Composition

Build designs from other designs and from the NetBox Device Type Library.

The compute rack doesn't describe its switch or its servers. It uses a design for each, and those designs take their device types from the NetBox Device Type Library. Building designs from smaller ones is composition.

Why compose

  • Swap a part without touching the rest. To fill the rack with a different server, point its devices entry at another server design. The rack, its cabling and every other rack stay as they are.
  • Write a device once. Every rack that uses devices/Dell_R640_w_module gets the same server, and a fix to that design reaches all of them.
  • Avoid one design for everything. A design that describes a whole data center in one file is hard to read, hard to change safely, and can't be reused. Small designs, each with one job, compose into large ones.

Designs from the catalogue: nbd:

An item with design: nbd:<catalogue name> includes another design from your catalogue in place of an object:

devices:
- design: nbd:devices/Dell_R640_w_module
  template_vars:
    name: R1-COMPUTE-01
    site: '{{ parent.site }}'
    rack: '{{ parent }}'
  • The name after nbd: is matched exactly against the catalogue names. nbd:devices/Dell_R640_w_module needs a design added as devices/Dell_R640_w_module.
  • Written like that, the rack uses whatever version of the server design the catalogue holds when you plan. nbd:devices/Dell_R640_w_module@1.0.0 pins it to that version, the way dtl: pins a library file to a commit, so the rack renders the same way until you change the pin.
  • The included design must be in the catalogue first. Adding a design whose nbd: designs aren't there is refused, naming the ones missing.
  • template_vars gives the included design its variables. Variables covers passing values down.
  • A design that others use can't be deleted while they use it.

Types from the Device Type Library: dtl:

A device type, module type or rack type can come from the NetBox Device Type Library:

device_type: 'dtl:device-types/Dell/PowerEdge-R640.yaml@fdf12828'
  • The path is the file's path in the library.
  • The @ suffix pins it to a commit (@fdf12828) or a tag. It's required, so a design renders the same way tomorrow as today, whatever changes in the library.
  • The type arrives with what the library defines for it: a device type's interfaces, power and console ports, and module bays.

NetBox Data Exchange at general availability

At general availability, designs will also take device types from NetBox Data Exchange, NetBox Labs' catalog of device types with lifecycle and operational data.

Nesting

Objects can also contain objects directly, as in your first design: a region's regions, a site's racks, a rack's devices, a device's modules. Inside a nested object, {{ parent }} refers to the object that contains it, and {{ parent.site }} to one of that object's fields. The compute rack passes rack: '{{ parent }}' and site: '{{ parent.site }}' to each device design, so each device lands in the rack, in the rack's site.

Composition reference has the full rules.

On this page