8.7 KiB
Terraform NetBox Provider Guide
*Source: https://registry.terraform.io/providers/e-breuninger/netbox/latest/docs*
Overview
The Terraform NetBox provider enables full lifecycle management of NetBox resources using Infrastructure as Code.
Version Compatibility
| NetBox Version | Provider Version |
|---|---|
| v4.3.0 - 4.4.0 | v5.0.0 and up |
| v4.2.2 - 4.2.9 | v4.0.0 - 4.3.1 |
| v4.1.0 - 4.1.11 | v3.10.0 - 3.11.1 |
| v4.0.0 - 4.0.11 | v3.9.0 - 3.9.2 |
| v3.7.0 - 3.7.8 | v3.8.0 - 3.8.9 |
| v3.6.0 - 3.6.9 | v3.7.0 - 3.7.7 |
| v3.5.1 - 3.5.9 | v3.6.x |
Important: NetBox makes breaking API changes even in non-major releases. Match provider version to NetBox version.
Provider Configuration
Basic Setup
terraform {
required_providers {
netbox = {
source = "e-breuninger/netbox"
version = "~> 5.0.0" # Match your NetBox version
}
}
}
provider "netbox" {
server_url = "https://netbox.spaceships.work"
api_token = var.netbox_api_token
}
Environment Variables
Configure via environment instead of hard-coding:
export NETBOX_SERVER_URL="https://netbox.spaceships.work"
export NETBOX_API_TOKEN="your-api-token-here"
# Provider auto-reads from environment
provider "netbox" {}
Configuration Schema
Required
api_token(String) - NetBox API authentication token- Environment:
NETBOX_API_TOKEN
- Environment:
server_url(String) - NetBox server URL (with scheme and port)- Environment:
NETBOX_SERVER_URL
- Environment:
Optional
-
allow_insecure_https(Boolean) - Allow invalid certificates- Environment:
NETBOX_ALLOW_INSECURE_HTTPS - Default:
false
- Environment:
-
ca_cert_file(String) - Path to PEM-encoded CA certificate- Environment:
NETBOX_CA_CERT_FILE
- Environment:
-
default_tags(Set of String) - Tags added to every resource- Useful for tracking Terraform-managed resources
-
headers(Map of String) - Custom headers for all requests- Environment:
NETBOX_HEADERS
- Environment:
-
request_timeout(Number) - HTTP request timeout (seconds)- Environment:
NETBOX_REQUEST_TIMEOUT
- Environment:
-
skip_version_check(Boolean) - Skip NetBox version validation- Environment:
NETBOX_SKIP_VERSION_CHECK - Default:
false - Useful for: Testing, unsupported versions
- Environment:
-
strip_trailing_slashes_from_url(Boolean) - Auto-fix URL format- Environment:
NETBOX_STRIP_TRAILING_SLASHES_FROM_URL - Default:
true
- Environment:
Usage Examples
Create IP Address
resource "netbox_ip_address" "server_ip" {
ip_address = "192.168.1.100/24"
dns_name = "docker-01-nexus.spaceships.work"
status = "active"
description = "Docker host - Nexus container registry"
tags = [
"terraform",
"production",
"dns-auto"
]
}
Create Device
resource "netbox_device" "proxmox_node" {
name = "foxtrot"
device_type = netbox_device_type.minisforum_ms_a2.id
role = netbox_device_role.hypervisor.id
site = netbox_site.homelab.id
primary_ip4 = netbox_ip_address.foxtrot_mgmt.id
tags = [
"terraform",
"proxmox",
"cluster-matrix"
]
comments = "Proxmox node in Matrix cluster - AMD Ryzen 9 9955HX"
}
Create Prefix
resource "netbox_prefix" "vlan_30_mgmt" {
prefix = "192.168.3.0/24"
vlan = netbox_vlan.management.id
status = "active"
description = "Management network for Proxmox cluster"
tags = [
"terraform",
"mgmt-network"
]
}
Create VLAN
resource "netbox_vlan" "management" {
vid = 30
name = "MGMT"
site = netbox_site.homelab.id
status = "active"
description = "Management VLAN for infrastructure"
tags = ["terraform"]
}
Integration Patterns
With Proxmox Provider
# Create VM in Proxmox
resource "proxmox_vm_qemu" "docker_host" {
name = "docker-01-nexus"
target_node = "foxtrot"
# ... vm config ...
}
# Register in NetBox
resource "netbox_ip_address" "docker_host_ip" {
ip_address = "192.168.1.100/24"
dns_name = "${proxmox_vm_qemu.docker_host.name}.spaceships.work"
description = "Docker host for Nexus registry"
tags = [
"terraform",
"production-dns",
"docker-host"
]
}
# DNS record auto-created by netbox-powerdns-sync plugin
Data Sources
Query existing NetBox data:
# Get all production IPs
data "netbox_ip_addresses" "production" {
filter {
name = "tag"
value = "production"
}
}
# Get device details
data "netbox_device" "proxmox_node" {
name = "foxtrot"
}
# Use in other resources
resource "proxmox_vm_qemu" "new_vm" {
target_node = data.netbox_device.proxmox_node.name
# ... config ...
}
Dynamic Inventory for Ansible
# Export NetBox data for Ansible
output "ansible_inventory" {
value = {
for device in data.netbox_devices.all.devices :
device.name => {
ansible_host = device.primary_ip4_address
device_role = device.role
site = device.site
tags = device.tags
}
}
}
Save to file:
terraform output -json ansible_inventory > inventory.json
Best Practices
1. Use Default Tags
Track all Terraform-managed resources:
provider "netbox" {
server_url = var.netbox_url
api_token = var.netbox_token
default_tags = ["terraform", "iac"]
}
2. Organize with Modules
module "vm_network" {
source = "./modules/netbox-vm"
vm_name = "docker-01"
ip_address = "192.168.1.100/24"
vlan_id = 30
dns_zone = "spaceships.work"
}
3. Use Variables for Secrets
Never hard-code tokens:
variable "netbox_api_token" {
description = "NetBox API token"
type = string
sensitive = true
}
4. State Management
Use remote state for team collaboration:
terraform {
backend "s3" {
bucket = "terraform-state"
key = "netbox/terraform.tfstate"
region = "us-east-1"
}
}
5. Version Pinning
Pin provider version to prevent breaking changes:
terraform {
required_providers {
netbox = {
source = "e-breuninger/netbox"
version = "= 5.0.0" # Exact version
}
}
}
Common Workflows
1. VM Provisioning Workflow
# 1. Reserve IP in NetBox
resource "netbox_ip_address" "vm_ip" {
ip_address = "192.168.1.100/24"
dns_name = "app-server.spaceships.work"
status = "reserved"
description = "Reserved for new application server"
}
# 2. Create VM in Proxmox
resource "proxmox_vm_qemu" "app_server" {
# ... config using netbox_ip_address.vm_ip.ip_address ...
}
# 3. Mark IP as active
resource "netbox_ip_address" "vm_ip_active" {
ip_address = netbox_ip_address.vm_ip.ip_address
status = "active" # Update status
description = "Application server - deployed ${timestamp()}"
}
2. DNS Automation Workflow
# Create IP with DNS name and auto-DNS tag
resource "netbox_ip_address" "service" {
ip_address = "192.168.1.200/24"
dns_name = "service-01-api.spaceships.work"
tags = [
"terraform",
"production-dns" # Triggers netbox-powerdns-sync
]
}
# DNS records created automatically by plugin
# No manual DNS configuration needed
3. Network Documentation Workflow
# Document entire network in NetBox
module "network_documentation" {
source = "./modules/network"
site_name = "homelab"
vlans = {
"mgmt" = { vid = 30, prefix = "192.168.3.0/24" }
"storage" = { vid = 40, prefix = "192.168.5.0/24" }
"ceph" = { vid = 50, prefix = "192.168.7.0/24" }
}
devices = var.proxmox_nodes
}
Troubleshooting
Version Mismatch Warning
Warning: NetBox version X.Y.Z is not officially supported by provider version A.B.C
Solution: Use matching provider version or set skip_version_check = true
API Authentication Errors
Error: authentication failed
Solution:
- Verify
api_tokenis valid - Check token has required permissions
- Ensure
server_urlincludes scheme (https://)
SSL Certificate Errors
Error: x509: certificate signed by unknown authority
Solution:
provider "netbox" {
server_url = var.netbox_url
api_token = var.netbox_token
ca_cert_file = "/path/to/ca.pem"
# OR for dev/testing only:
# allow_insecure_https = true
}
Trailing Slash Issues
Error: invalid URL format
Solution: Remove trailing slashes from server_url or let provider auto-fix:
provider "netbox" {
server_url = "https://netbox.example.com" # No trailing slash
strip_trailing_slashes_from_url = true # Auto-fix if present
}