black framed eyeglasses on computer screen

NetBox + MikroTik Automation with Python or Ansible

You manage MikroTik devices through WinBox and track IP addresses in a spreadsheet. You configure each CRS switch and CCR router by hand. This process does not scale. Config drift creeps in. Documentation goes stale. One typo in a VLAN ID breaks a site.This guide shows you how to fix that problem. You will connect NetBox, a source-of-truth platform, to your MikroTik fleet using Python and Ansible. You will see real code, real playbooks, and the mistakes engineers make when they start this journey.

Table of Contents


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:

  1. Create a Manufacturer named “MikroTik.”
  2. Create Device Types for each hardware model you run, for example CCR2004-1G-12S+2XS and CRS326-24G-2S+.
  3. Create a Platform named “RouterOS” and associate it with your MikroTik devices.
  4. 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.command module always reports changed, since it sends raw commands. Use changed_when to control this behavior.
  • The community.routeros.api_modify module checks state before making changes and supports proper idempotency.
  • Ansible --check mode 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

 

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *