Docs
Reference

Expressions and loops

Expressions, filters, arithmetic and loops in a design.

Expressions

An expression is written in {{ }} inside a YAML string, and can stand for a whole value or part of one. The string must be quoted: name: {{ variables.site_name }} without quotes is a YAML mapping to YAML, not text, and the Add design dialog says so at that line.

PatternExampleGives
A variable'{{ variables.site_name }}'The variable's value
The containing object'{{ parent }}'The object that holds this one
A field of it'{{ parent.site }}'That object's site
The loop's variable'{{ loop.i }}'The current pass of the loop
A filter'{{ loop.i | zeropad }}'01, 02 and so on
Arithmetic'{{ loop.i * 2 - 1 }}'A number worked out per pass
A function"{{ nbd.lookup.endpoint('SW-01', 'Interface', 'eth0') }}"The object the function finds
Part of a value'{{ variables.rack_name }}-TOR-01'Text with the value in it

A function stands for the whole value: "{{ nbd.lookup.endpoint(...) }}" with nothing around it. Text around a function is refused, since what a function finds is an object, not text. A function's arguments can hold expressions of their own, which are worked out first. Write the outer string in double quotes so its arguments can be in single quotes, as in the compute rack's cables.

Filters

A filter follows a value after |, one to an expression:

FilterDoesExample
zeropadPads a number to two digits7 becomes 07
zeropad(N)Pads a number to N digitszeropad(3) makes 7 into 007
lowerLower-cases textDC1 becomes dc1
upperUpper-cases textdc1 becomes DC1
slugifyMakes a NetBox slug: lower-case letters and digits joined by single hyphensStore 001 (US-West) becomes store-001-us-west
host(N)The Nth address of a prefix, written with the prefix's length, for an IP address's address10.0.0.8/31 | host(1) becomes 10.0.0.9/31

Any other filter, or two in one expression, refuses the render.

When an expression can't be worked out

An expression the render can't resolve refuses the render, naming the object and the field: a loop's variable outside its loop, a variable the design doesn't declare, or a chain of filters.

Braces that aren't one of these expressions are text, and NetBox gets them as written. A config template's own {{ device.name }} is text the design means.

Loops

nbd_loop repeats an object, or a group of objects, once per pass:

devices:
- nbd_loop:
    over: {start: 1, end: 10}
    as: i
  infra_type: Device
  name: 'SERVER-{{ loop.i | zeropad }}'

over takes:

FormPasses
{start: 1, end: 10}1 to 10, both included
31 to 3
[red, green, blue]Each item, in order
'{{ variables.shelf_count }}'As the variable says: a count, a {start, end} mapping, or a list

A bound may be one of the design's variables, so one design covers a rack with six power shelves and one with eight: over: {start: 1, end: '{{ variables.shelf_count }}'} with shelf_count declared under variables and given on the deploy. Only the design's variables can set a bound: the loop expands before its own loop.*, the parent object or any function exists, and a bound naming those is refused saying so. A value that is not a whole number is refused too, naming the loop.

as names the loop's variable. Inside the loop, with as: i:

VariableIs
loop.iThe pass number, or for a list, the item
loop.indexThe pass, counting from 1
loop.index0The pass, counting from 0
loop.first, loop.lastWhether this is the first or last pass
loop.lengthHow many passes there are

To repeat several objects together, list them under items:

cables:
- nbd_loop:
    over: {start: 1, end: 3}
    as: i
  items:
  - infra_type: Cable
    label: 'CABLE-A-{{ loop.i }}'
  - infra_type: Cable
    label: 'CABLE-B-{{ loop.i }}'

A loop can also repeat an included design: put design: and template_vars: beside nbd_loop, as the compute rack does for its servers.

On this page