NetBox + MikroTik Automation with Python or Ansible
Table of Contents
- 1. Why Automate MikroTik with NetBox?
- 2. Core Concepts Before You Start
- 3. Setting Up Your Environment
- 4. Method 1: Automating MikroTik with Python and NetBox
- 5. Method 2: Automating MikroTik with Ansible and NetBox
- 6. Python vs. Ansible for MikroTik: Which Should You Choose?
- 7. Real-World Use Cases
- 8. Common Pitfalls and Lessons Learned
- 9. Best Practices Checklist
- 10. Conclusion: Start Small, Scale Your MikroTik Automation
- 11. FAQ
1. Why Automate MikroTik with NetBox?
The problem with manual RouterOS management at scale
Manual configuration works for five devices. It fails for fifty. Each engineer configures devices slightly differently. VLAN numbering drifts between sites. Nobody remembers which router got the firmware update last month. Automation removes this inconsistency.
- Manual changes do not scale past a small device count.
- Human error causes most outages, not hardware failure.
- Spreadsheets and personal notes go out of date within weeks.
- New engineers cannot safely make changes without full context.
NetBox as “source of truth” vs. just documentation
NetBox does not configure your devices. It stores what your network should look like: device types, IP addresses, VLANs, sites, and interfaces. Automation tools like Python scripts or Ansible playbooks read that data from NetBox and push it to your MikroTik devices. NetBox plans the network. Automation tools build it.
This distinction matters. Many teams populate NetBox first, then discover they still configure devices by hand. NetBox only delivers value when something consumes its data and acts on it.
Who this guide is for
- ISPs and WISPs running fleets of CCR routers and CRS switches
- Enterprises using MikroTik at the network edge or in branch offices
- Network engineers who manage more than 20 MikroTik devices
- System administrators who already use NetBox for IPAM or DCIM and want to extend it into configuration management
2. Core Concepts Before You Start
The NetBox data model
NetBox organizes network data into a small set of core object types. You will reference these constantly in your scripts and playbooks:
- Sites: physical locations, such as a POP or branch office
- Devices: individual MikroTik routers or switches
- Device Types: hardware models, such as CCR2004-1G-12S+2XS or CRS326-24G-2S+
- Interfaces: physical and logical ports on a device
- IPAM: IP prefixes, addresses, and VLANs
- Custom Fields: extra attributes you define, such as an “automation-enabled” flag
- Config Contexts: structured JSON data you attach to devices, sites, or roles for use in templates
RouterOS API vs. SSH scripting
MikroTik devices expose two automation paths. Choose based on your task:
- RouterOS API (port 8728, or 8729 for API-SSL): a structured binary protocol. Tools parse responses as data, not text. Use this for scripts that read or write configuration programmatically.
- SSH/CLI scripting: you send RouterOS CLI commands over SSH and parse text output. Use this when a task has no API equivalent, or when your tooling already targets SSH-based network devices.
Enable the API service before you automate anything:
/ip service
set api disabled=no port=8728
set api-ssl disabled=no port=8729
Restrict API access to your automation host. Do not expose port 8728 or 8729 to the internet:
/ip service
set api address=10.0.0.0/24
set api-ssl address=10.0.0.0/24
Python vs. Ansible: a decision framework
| Factor | Python | Ansible |
|---|---|---|
| Learning curve | Requires programming knowledge | YAML syntax, lower barrier for network engineers |
| Idempotency | You build it yourself | Built into most modules |
| Custom logic | Full control, any library | Limited to module and plugin capabilities |
| Best use case | Bidirectional sync, custom NetBox scripts, complex logic | Bulk config push, repeatable playbooks, team collaboration |
| Team skill fit | Developers, automation engineers | Network engineers new to coding |
3. Setting Up Your Environment
Installing and configuring NetBox
NetBox setup is outside the scope of this guide. Use the official NetBox Docker project or the Debian/Ubuntu install guide from the NetBox documentation. This guide assumes a running NetBox instance with API access and a valid API token.
Adding MikroTik device types and platform in NetBox
Before you automate anything, model your hardware in NetBox:
- Create a Manufacturer named “MikroTik.”
- Create Device Types for each hardware model you run, for example CCR2004-1G-12S+2XS and CRS326-24G-2S+.
- Create a Platform named “RouterOS” and associate it with your MikroTik devices.
- Add each physical device with its site, role, and serial number.
Enabling the RouterOS API
Enable API access on every device you plan to automate, as shown in the previous section. Confirm connectivity from your automation host:
# Test TCP connectivity to the API port
nc -zv 10.0.0.1 8728
Required Python packages
pip install pynetbox librouteros
- pynetbox: official Python client for the NetBox REST API
- librouteros: Python client for the RouterOS API, also used internally by the Ansible community.routeros collection
Required Ansible collections
ansible-galaxy collection install netbox.netbox
ansible-galaxy collection install community.routeros
ansible-galaxy collection install ansible.netcommon
4. Method 1: Automating MikroTik with Python and NetBox
Connecting to NetBox with pynetbox
import pynetbox
nb = pynetbox.api(
"https://netbox.example.com",
token="YOUR_NETBOX_API_TOKEN"
)
# Get all MikroTik devices tagged for automation
devices = nb.dcim.devices.filter(manufacturer="mikrotik", tag="automation")
for device in devices:
print(device.name, device.primary_ip4)
Connecting to a MikroTik device with librouteros
from librouteros import connect
api = connect(
username="automation",
password="YOUR_PASSWORD",
host="10.0.0.1"
)
# Read all interfaces from the device
interfaces = list(api("/interface/print"))
for iface in interfaces:
print(iface["name"], iface["type"])
Example: syncing MikroTik interfaces into NetBox
This script pulls live interface data from a MikroTik device and creates matching interface records in NetBox. Run scripts like this once, then audit the results before trusting them.
import pynetbox
from librouteros import connect
nb = pynetbox.api("https://netbox.example.com", token="YOUR_NETBOX_API_TOKEN")
api = connect(username="automation", password="YOUR_PASSWORD", host="10.0.0.1")
device = nb.dcim.devices.get(name="edge-router-01")
for iface in api("/interface/print"):
existing = nb.dcim.interfaces.get(device_id=device.id, name=iface["name"])
if existing:
continue
nb.dcim.interfaces.create(
device=device.id,
name=iface["name"],
type="other",
enabled=(iface.get("disabled") == "false")
)
print(f"Created interface {iface['name']} on {device.name}")
Example: pushing VLAN configuration from NetBox to MikroTik
This script reads VLANs assigned to a site in NetBox and creates matching VLAN interfaces on the MikroTik device.
import pynetbox
from librouteros import connect
nb = pynetbox.api("https://netbox.example.com", token="YOUR_NETBOX_API_TOKEN")
api = connect(username="automation", password="YOUR_PASSWORD", host="10.0.0.1")
site = nb.dcim.sites.get(slug="branch-office-01")
vlans = nb.ipam.vlans.filter(site_id=site.id)
for vlan in vlans:
api(
"/interface/vlan/add",
name=f"vlan{vlan.vid}",
vlan_id=vlan.vid,
interface="bridge1"
)
print(f"Created VLAN {vlan.vid} ({vlan.name}) on the device")
Error handling and idempotency in Python
Raw Python scripts do not check state before making changes by default. Build this logic yourself:
- Query existing configuration before you add anything.
- Wrap API calls in try/except blocks and log every failure.
- Compare NetBox data against live device state before pushing changes.
- Log every change with a timestamp for audit purposes.
try:
api("/interface/vlan/add", name="vlan100", vlan_id=100, interface="bridge1")
except Exception as error:
print(f"Failed to create VLAN 100: {error}")
When to wrap this in a web interface or NetBox custom script
Standalone scripts work for one-off tasks. Move to a NetBox custom script or a small Flask/Django app when you need:
- A button-click interface for non-CLI users
- Scheduled, recurring synchronization
- An audit trail visible inside NetBox itself
5. Method 2: Automating MikroTik with Ansible and NetBox
Building a dynamic inventory from NetBox
The netbox.netbox.nb_inventory plugin turns your NetBox devices into an Ansible inventory automatically. Create netbox_inventory.yml:
plugin: netbox.netbox.nb_inventory
api_endpoint: https://netbox.example.com
token: YOUR_NETBOX_API_TOKEN
validate_certs: true
config_context: true
query_filters:
- platform: routeros
- tag: automation
group_by:
- site
- device_role
Test the inventory:
ansible-inventory -i netbox_inventory.yml --list
Connection variables for RouterOS over SSH
Set these host variables to connect to RouterOS devices using the SSH-based modules:
ansible_connection: ansible.netcommon.network_cli
ansible_network_os: community.routeros.routeros
ansible_user: automation
ansible_password: "{{ vault_routeros_password }}"
ansible_become: true
ansible_become_method: enable
Connection variables for the RouterOS API
The API-based modules, such as community.routeros.api, require a local connection instead:
ansible_connection: local
Sample playbook: provisioning VLANs from NetBox data
This playbook reads VLAN data already present in NetBox config context and creates matching VLANs on each MikroTik device using the API module.
---
- name: Provision VLANs from NetBox on MikroTik devices
hosts: routeros
gather_facts: false
connection: local
tasks:
- name: Create VLAN interfaces from NetBox config context
community.routeros.api_modify:
hostname: "{{ ansible_host }}"
username: "{{ ansible_user }}"
password: "{{ ansible_password }}"
path: interface vlan
data:
- name: "vlan{{ item.vid }}"
vlan_id: "{{ item.vid }}"
interface: bridge1
loop: "{{ config_context.vlans }}"
Sample playbook: pushing config with Jinja2 templates
Generate a RouterOS configuration script from a Jinja2 template, then apply it with the command module over SSH.
templates/vlans.j2:
{% for vlan in config_context.vlans %}
/interface vlan add name=vlan{{ vlan.vid }} vlan-id={{ vlan.vid }} interface=bridge1
{% endfor %}
Playbook:
---
- name: Generate and apply RouterOS VLAN config
hosts: routeros
gather_facts: false
tasks:
- name: Render VLAN config from template
ansible.builtin.template:
src: templates/vlans.j2
dest: "/tmp/{{ inventory_hostname }}_vlans.rsc"
delegate_to: localhost
- name: Read generated commands
ansible.builtin.set_fact:
vlan_commands: "{{ lookup('file', '/tmp/' + inventory_hostname + '_vlans.rsc') }}"
- name: Apply VLAN commands to device
community.routeros.command:
commands: "{{ vlan_commands.splitlines() }}"
Idempotency and dry-run limitations
- The
community.routeros.commandmodule always reportschanged, since it sends raw commands. Usechanged_whento control this behavior. - The
community.routeros.api_modifymodule checks state before making changes and supports proper idempotency. - Ansible
--checkmode has limited support on RouterOS. Test playbooks in a lab first, using RouterOS CHR in GNS3 or a virtual lab.
Handling both CRS switches and CCR routers with shared playbooks
MikroTik switches and routers run the same RouterOS operating system. You can reuse most playbooks across both hardware families. Separate device-type-specific settings, such as port counts or SFP layout, into NetBox config context or group variables, and keep your task logic generic.
6. Python vs. Ansible for MikroTik: Which Should You Choose?
- Choose Python when you need custom logic, bidirectional sync between NetBox and MikroTik, or integration with a web application.
- Choose Ansible when you need repeatable, auditable playbooks that a team can review and run without writing code.
- Choose both when you want Ansible for orchestration and scheduled runs, with Python scripts or custom modules handling logic that standard Ansible modules cannot express.
Many teams start with Ansible for its lower barrier to entry, then introduce Python for tasks Ansible modules do not cover well, such as complex NetBox data transformations.
7. Real-World Use Cases
Automated onboarding of new MikroTik devices
- Add the device record to NetBox with its site, role, and management IP.
- Run a playbook that pushes baseline configuration: hostname, NTP, SNMP, and management access rules.
- Tag the device as “automation-managed” once the baseline succeeds.
Bulk VLAN and firewall rule deployment
- Define VLANs once in NetBox IPAM.
- Run a single playbook against every device tagged for a site.
- Roll out firewall rule changes fleet-wide from one source instead of editing each device.
Automated backup and config drift detection
- Pull the running configuration from each device on a schedule.
- Store backups in version control, such as Git.
- Compare live device state against NetBox records and flag mismatches.
Continuous compliance checks
- Verify NTP servers match the approved list.
- Verify SNMP community strings meet security policy.
- Verify RouterOS version meets the minimum supported release.
8. Common Pitfalls and Lessons Learned
- Stale NetBox data: automation is only as accurate as the data behind it. Bad data in NetBox produces bad configuration on your devices.
- RouterOS version differences: RouterOS v7 changed API behavior and command syntax in several areas compared to v6. Test scripts against your actual firmware version before production use.
- Secrets management: never hardcode passwords in scripts or playbooks. Use Ansible Vault, environment variables, or a secrets manager.
- Full auto-discovery into NetBox: avoid tools that fully auto-populate NetBox from live network scans. Curate your source-of-truth data manually, then automate the push to devices. Auto-discovery tends to import noise and inconsistent naming.
- Skipping the lab: test every new playbook or script against RouterOS CHR (Cloud Hosted Router) in a virtual lab before you run it against production hardware.
9. Best Practices Checklist
- Test every playbook or script in a lab using RouterOS CHR or GNS3 first.
- Pin your Ansible collection and Python package versions in requirements files.
- Tag only the devices you intend to automate in NetBox, and scope playbooks to that tag.
- Start with read-only scripts that report state before you write scripts that change configuration.
- Store all secrets in Ansible Vault or a secrets manager, never in plain text.
- Version-control your playbooks, scripts, and Jinja2 templates in Git.
- Log every automated change with a timestamp and the source system.
- Review NetBox data accuracy before you trust it as automation input.
10. Conclusion: Start Small, Scale Your MikroTik Automation
Automating MikroTik with NetBox removes manual errors and gives your team a single source of truth. Start with a small, low-risk task, such as pulling interface data into NetBox with Python or pushing a single VLAN with Ansible. Expand from there.
Choose Python when you need custom logic. Choose Ansible when you need repeatable, team-reviewed playbooks. Many teams use both together. Whichever path you take, test in a lab first, keep your NetBox data accurate, and automate one task at a time.
11. FAQ
Does NetBox support MikroTik natively?
NetBox supports any vendor as a data model. You define MikroTik as a manufacturer, add your device types, and set the platform to RouterOS. NetBox does not include built-in MikroTik configuration push; that function comes from Ansible or Python scripts you connect to NetBox.
Can I use Ansible without NetBox for MikroTik automation?
Yes. Ansible works with static inventory files instead of NetBox. You lose the dynamic, centralized source of truth that NetBox provides, and you maintain inventory data by hand instead.
Is the RouterOS API better than SSH for automation?
The RouterOS API returns structured data, which is easier and more reliable to parse than SSH text output. Use the API for most automation tasks. Use SSH when you need a command with no API equivalent.
Does this work with RouterOS v7?
Yes. The RouterOS API, librouteros, and the community.routeros Ansible collection all support RouterOS v7. Some command syntax changed between v6 and v7. Test your scripts and playbooks against your specific RouterOS version before production use.
Check our list of MikroTik guides