Idempotent bootstrap of a fresh NetBox instance from declarative YAML variable files. Covers users, groups, object permissions, custom fields, tags, webhooks, export templates, DCIM structure, IPAM structure, tenancy, and cloud inventory (AWS managed services).
Two companion export scripts snapshot configuration into the YAML variable files, giving you a repeatable "configuration as code" workflow: export once, commit, apply anywhere.
scripts/export_netbox.py— snapshot a live NetBox instance intovars/scripts/export_aws_ec2.py— populate EC2 instance types intovars/virtual_machine_types.ymlscripts/export_aws_rds.py— populate RDS DB instances intovars/rds_instances.yml
- Ansible >= 2.20
Install before running the role:
ansible-galaxy collection install netbox.netbox| Collection | Purpose |
|---|---|
netbox.netbox |
NetBox API modules (tags, sites, device roles, etc.) |
The export scripts require:
cd scripts/
pip install -r requirements.txtThe role itself does not require any additional Python packages on the control node beyond Ansible's standard dependencies.
- NetBox >= 4.0 for all structural sections
- NetBox >= 4.6 for
virtual_machine_types(VirtualMachineTypewas added in 4.6.0) - An API token with write access to the objects you intend to bootstrap
| OS | Versions |
|---|---|
| Debian | bookworm, trixie |
| Ubuntu | jammy, noble, resolute |
All variables have defaults defined in defaults/main.yml.
| Variable | Default | Description |
|---|---|---|
netbox_url |
https://netbox.example.com |
Base URL of the target NetBox instance |
netbox_api_token |
{{ vault_netbox_api_token }} |
API token (store in Ansible Vault) |
netbox_validate_certs |
true |
Validate TLS certificates |
netbox_minimum_version |
4.0.0 |
Minimum NetBox version required (checked in preflight) |
| Variable | Default | Description |
|---|---|---|
netbox_bootstrap_default_password |
{{ vault_netbox_bootstrap_default_password }} |
Initial password for bootstrapped users (store in Vault) |
Users are created with this password and should change it on first login.
| Variable | Default | Description |
|---|---|---|
netbox_rds_cluster |
AWS RDS |
NetBox cluster name to assign RDS instances to. Override per environment. |
The cluster and cluster type are defined in vars/clusters.yml and vars/cluster_types.yml. Override netbox_rds_cluster in your playbook vars when running a per-region export (e.g. AWS RDS us-east-1).
Each bootstrap section can be enabled or disabled independently. All sections are enabled by default.
| Variable | Default | Section |
|---|---|---|
netbox_bootstrap_groups |
true |
User groups |
netbox_bootstrap_users |
true |
Local users |
netbox_bootstrap_permissions |
true |
Object permissions |
| Variable | Default | Section |
|---|---|---|
netbox_bootstrap_tags |
true |
Tags |
netbox_bootstrap_custom_fields |
true |
Custom fields |
netbox_bootstrap_custom_links |
true |
Custom links |
netbox_bootstrap_webhooks |
true |
Webhooks |
netbox_bootstrap_export_templates |
true |
Export templates |
| Variable | Default | Section |
|---|---|---|
netbox_bootstrap_tenant_groups |
true |
Tenant groups |
netbox_bootstrap_tenants |
true |
Tenants |
netbox_bootstrap_contact_groups |
true |
Contact groups |
netbox_bootstrap_contact_roles |
true |
Contact roles |
netbox_bootstrap_contacts |
true |
Contacts |
| Variable | Default | Section |
|---|---|---|
netbox_bootstrap_regions |
true |
Regions |
netbox_bootstrap_site_groups |
true |
Site groups |
netbox_bootstrap_sites |
true |
Sites |
netbox_bootstrap_locations |
true |
Locations |
netbox_bootstrap_rack_roles |
true |
Rack roles |
netbox_bootstrap_device_roles |
true |
Device roles |
netbox_bootstrap_manufacturers |
true |
Manufacturers |
netbox_bootstrap_device_types |
true |
Device types |
netbox_bootstrap_platforms |
true |
Platforms |
| Variable | Default | Section |
|---|---|---|
netbox_bootstrap_ipam_roles |
true |
IPAM roles |
netbox_bootstrap_rirs |
true |
RIRs |
netbox_bootstrap_aggregates |
true |
IP aggregates |
netbox_bootstrap_vrfs |
true |
VRFs |
netbox_bootstrap_route_targets |
true |
Route targets |
netbox_bootstrap_vlan_groups |
true |
VLAN groups |
| Variable | Default | Section |
|---|---|---|
netbox_bootstrap_virtual_machine_types |
true |
VM types (EC2 families + AWS service categories) |
netbox_bootstrap_cluster_types |
true |
Cluster types (e.g. Cloud) |
netbox_bootstrap_clusters |
true |
Clusters (e.g. AWS RDS, AWS ELB) |
| Variable | Default | Section |
|---|---|---|
netbox_bootstrap_rds_instances |
true |
AWS RDS DB instances as NetBox virtual machines |
All three scripts live in scripts/ and share the same .env file. Install dependencies once:
cd scripts/
pip install -r requirements.txt
cp .env.example .env
# Edit .env — see .env.example for all variablesConfiguration precedence for every script (last wins):
.env (scripts/ directory) → --env-file <path> → explicit CLI flags
Snapshots a live NetBox instance into vars/. Run this to capture your source-of-truth NetBox configuration before bootstrapping a new instance.
# Boilerplate sections only (default)
python export_netbox.py
# Everything including site-specific data
python export_netbox.py --sections all
# Specific sections
python export_netbox.py --sections groups,permissions,device_roles
# Dry run
python export_netbox.py --dry-run --verboseRequired .env variables:
NETBOX_URL=https://netbox.corp.example.com
NETBOX_TOKEN=nbt_xxxx.<your-token>Populates vars/virtual_machine_types.yml with EC2 instance type definitions (vcpus, memory, architecture). Defaults to the t and m families.
python export_aws_ec2.py --region us-east-1
python export_aws_ec2.py --region us-east-1 --families t,m,c --current-gen-only
python export_aws_ec2.py --region us-east-1 --dry-run --verboseCredentials are resolved via the standard AWS credential chain (~/.aws, environment variables, instance profile). Pass --profile to select a named profile.
Populates vars/rds_instances.yml with running RDS DB instances. These are pushed to NetBox as virtual machines under the AWS RDS cluster (Tier 7).
python export_aws_rds.py --region us-east-1
python export_aws_rds.py --region us-east-1 --engines postgres,mysql
python export_aws_rds.py --region us-east-1 --status available
python export_aws_rds.py --region us-east-1 --dry-run --verboseCommit the resulting vars/*.yml to version control. These files are the source of truth for your bootstrap configuration. Do not hand-edit them — re-run the export script to update.
Sections are applied in strict dependency order inside tasks/main.yml. The order matters:
- Preflight — connectivity and variable checks
- Users & Access — groups → users → permissions
- Extras — tags → custom fields → custom links → webhooks → export templates
- Tenancy — tenant groups → tenants → contact groups → contact roles → contacts
- DCIM structure — regions → site groups → sites → locations → rack roles → device roles → manufacturers → device types → platforms
- Virtualization — virtual machine types → cluster types → clusters
- Cloud Inventory — RDS instances (requires clusters from step 6)
- IPAM structure — IPAM roles → RIRs → aggregates → VRFs → route targets → VLAN groups
The role tracks AWS managed services as NetBox virtual machines for invoice reconciliation. The pattern is:
- Tenant → AWS account
- Site → AWS region (
us-east-1,eu-west-1, etc.) - VirtualMachineType → service tier (
Application Load Balancer,EFS Standard, etc.) - Cluster → service family (
AWS RDS,AWS ELB,AWS EFS,AWS Route53,AWS SES) - Virtual Machine → each individual service instance
vars/virtual_machine_types.yml includes type definitions for all common AWS service tiers out of the box. vars/clusters.yml defines one cluster per service family under the Cloud cluster type.
To add a new AWS service family, add its type entries to vars/virtual_machine_types.yml, add its cluster to vars/clusters.yml, write an export script following the export_aws_rds.py pattern, and add a task file and toggle following the rds_instances pattern.
---
- name: Bootstrap NetBox instance
hosts: localhost
gather_facts: false
roles:
- role: ansible-role-netbox-bootstrap
vars:
netbox_url: "https://netbox.example.com"
netbox_api_token: "{{ vault_netbox_api_token }}"---
- name: Bootstrap NetBox — structural config only
hosts: localhost
gather_facts: false
roles:
- role: ansible-role-netbox-bootstrap
vars:
netbox_url: "https://netbox.example.com"
netbox_api_token: "{{ vault_netbox_api_token }}"
netbox_bootstrap_virtual_machine_types: false
netbox_bootstrap_cluster_types: false
netbox_bootstrap_clusters: false
netbox_bootstrap_rds_instances: falseStore sensitive values in group_vars/all/vault.yml (Ansible Vault encrypted):
vault_netbox_api_token: "nbt_xxxx.<token>"
vault_netbox_bootstrap_default_password: "ChangeMe123!"Reference them in group_vars/all/vars.yml:
netbox_api_token: "{{ vault_netbox_api_token }}"
netbox_bootstrap_default_password: "{{ vault_netbox_bootstrap_default_password }}"Run with:
ansible-playbook realtime.bootstrap_netbox.yml --ask-vault-passAll tasks are idempotent. Re-running against an already-bootstrapped instance is safe. Objects are matched by slug or name. Existing objects are updated if their attributes differ from the var files; objects in NetBox that are not present in the var files are left untouched.
MIT
Bob Tanner