terraform-netbox

YAML-driven Terraform/Terragrunt for the NetBox catalogue: the stable reference data a host is planned against. Device records are not here.

Ownership split

Owner Objects
this repo sites, prefixes, DHCP pool ranges, gateways, managed IPs, VLAN groups + VLANs, device types, manufacturers, device roles, platforms, custom-field definitions, network profiles
autodiscovery agent device records, interfaces, MAC addresses, switch cabling
UI host names, role assignment, IP allocation (inventory -> planned)

Writing a device from here would fight both of them, so the module declares no netbox_device. The handful of network switches are created by hand in the NetBox UI; this repo only defines the chassis_mac field discovery matches them on.

Supersedes terraform-infra, which also drove Kea DHCP. Kea is managed by the kea-operator CRs in argocd-apps (apps/base/dhcp-system/cr/).

Layout

config/<region>/<dc>/sites.yaml                          # site slug -> name/description
config/<region>/<dc>/subnets/net-<a>-<b>-<c>-<d>-<len>.yaml
config/<region>/<dc>/device-types/<slug>.yaml            # manufacturer, model
config/<region>/<dc>/device-roles.yaml
config/<region>/<dc>/platforms.yaml                      # slug -> display name
config/<region>/<dc>/vlans.yaml                          # keyed per site
config/<region>/<dc>/network-profiles/<name>.yaml
config/<region>/<dc>/custom-fields.yaml                  # custom-field DEFINITIONS
config/<region>/<dc>/managed-ips.yaml
environments/<region>/<dc>/terragrunt.hcl
modules/netbox/

make plan / make apply reconcile the YAML against NetBox. State lives in Consul under infra/terraform/netbox/<region>/<dc>/state. A site that already exists in NetBox must be imported, not re-created: site names are unique.

Subnets (subnets/net-<a>-<b>-<c>-<d>-<len>.yaml)

The filename carries the network and mask length; the human label lives in description.

prefix: 198.18.15.0/24
description: syd1 production
site: syd1            # NetBox site slug
router: 254           # host-octet int -> gateway IP
dhcp:                 # omit for a NetBox-only prefix
  enabled: true
  start: 200          # host-octet int
  stop: 220
dns: [198.18.200.7]
domain: main.unkin.net
next_server: 198.18.19.19

Creates netbox_prefix, plus a netbox_ip_range with role dhcp and the gateway netbox_ip_address. dns, domain and next_server are read by no resource today; they are retained so a later change can drive Kea from this repo without re-deriving them.

Device types (device-types/<slug>.yaml)

manufacturer: Dell
model: OptiPlex 3070
u_height: 1

VLANs (vlans.yaml)

Keyed per site. Each site gets its own site-scoped netbox_vlan_group, so the same VID may exist in more than one site.

syd1:
  vid_ranges: [[1, 4094]]
  vlans:
    - vid: 101
      name: fabric_common_01

Network profiles (network-profiles/<name>.yaml)

A profile describes the interfaces a logical host should have. It is published as a netbox_config_context scoped to its sites (and roles, if given), so the UI reads profiles from the NetBox API rather than from git.

description: Dual-homed fabric host
sites: [syd1]
weight: 1000
interfaces:
  - name: fabric0
    vlan: 101                       # VID in the site's VLAN group
    subnet: net-198-18-13-0-24      # subnet key; the prefix is resolved into the context
    subinterfaces: []               # optional, same shape

Custom fields (custom-fields.yaml)

Field definitions for what bootapi reads: pxe_enabled, provision_template, domain, nameservers, gateway; plus chassis_mac, which autodiscovery matches an LLDP neighbour on. content_types are NetBox app_label.model strings. pxe_enabled's value is deliberately not managed here — it is runtime state cleared by bootapi's /provisioned callback.

Providers + auth

Provider Source
netbox e-breuninger/netbox 4.3.0
vault hashicorp/vault 5.6.0

The NetBox token is minted per run from the Vault netbox engine (netbox/creds/terraform-netbox) and lease-revoked when the run ends; Consul state creds come from consul_root/au/syd1/creds/terraform-netbox. Both are granted to the terraform_netbox AppRole and the woodpecker_terraform_netbox k8s role in terraform-vault.

S
Description
YAML-driven Terraform for NetBox: prefixes, IPs, devices, platforms and custom fields
Readme 102 KiB