Configuration of OpenWrt devices over SSH, without Python on the target. Every role drives UCI directly: system, network, wireless, mesh, firewall, DHCP/DNS, Wireguard, policy-based routing, SSH and a Prometheus exporter.
These roles configure a device that already runs OpenWrt. Flashing the firmware is out of scope.
-
ansible-core >=2.16on the controller -
Collections:
ansible.utils >=2.5.0(thewireguardrole usesipmath) -
The
gekmihesg.openwrtrole. It supplies theuciandopkgmodules and the action-plugin monkeypatch that rewritesansible.builtin.*calls into shell equivalents. Every role here depends on it, and it is resolved throughroles_path, not as a collection. -
Task
>=3.20, for the helper targets only -
SSH access to the device as
root
Installing the dependencies:
ansible-galaxy collection install -r requirements.yml
ansible-galaxy role install -r requirements.yml -p .ansible/roles
pip install -r requirements.txtOr, equivalently, task install.
Installing the collection itself:
ansible-galaxy collection install git+https://github.com/flyoverhead/ansible-openwrt.gitFull documentation and usage examples of role <role> can be found in
roles/<role>/README.md.
Order matters. Run extroot first — it migrates the overlay onto USB and
reboots, so anything committed before it lands on the overlay that is about to
be replaced. system and network come next, since later roles attach to the
interfaces network defines. batman or mesh11sd must precede wireless,
because both create wireless interfaces of their own. Everything after that is
independent.
---
- name: configure openwrt devices
hosts: openwrt
ignore_unreachable: true
gather_facts: false
roles:
- flyoverhead.openwrt.extroot
- flyoverhead.openwrt.system
- flyoverhead.openwrt.network
- flyoverhead.openwrt.batman
- flyoverhead.openwrt.wireless
- flyoverhead.openwrt.wireguard
- flyoverhead.openwrt.firewall
- flyoverhead.openwrt.pbr
- flyoverhead.openwrt.dropbear
- flyoverhead.openwrt.dhcp
- flyoverhead.openwrt.node_exportergather_facts must be false: fact gathering needs Python, which these devices
do not have.
A complete, working configuration for two devices lives under
tests/ and is the reference this collection is developed against:
| File | Contents |
|---|---|
tests/group_vars/openwrt.yml |
Everything shared: network, wireless, mesh, DHCP, Wireguard, firewall, PBR, dropbear |
tests/host_vars/archer.yml |
Per-device settings for a TP-Link Archer C7 |
tests/host_vars/mikrotik.yml |
Per-device settings for a MikroTik hAP ac² |
That configuration:
- Enables extroot on an external USB device
- Creates an IoT network isolated from LAN, and disables the WAN IPv6 interface
- Builds a B.A.T.M.A.N. mesh, separating LAN and IoT over VLAN ports
bat0.2andbat0.3 - Replaces the stock APs with LAN (5 GHz) and IoT (2.4 and 5 GHz) APs, with 802.11r fast BSS transition
- Configures dnsmasq, DHCP pools and static leases
- Creates one Wireguard interface for inbound remote access and one for routing out through a VPS
- Sets firewall zones, forwardings, rules and redirects
- Routes selected domains through the VPS with policy-based routing
| OS | Status |
|---|---|
| OpenWrt 23.05 | Supported |
| OpenWrt 22.03 | Supported |
| OpenWrt 24.10 and newer | Not supported — see Gotchas |
Tested on:
| Name | Description |
|---|---|
batman |
B.A.T.M.A.N. adv mesh interfaces and mesh-capable wpad |
dhcp |
dnsmasq options, DHCP pools and static leases |
dropbear |
Dropbear SSH daemon settings and authorized keys |
extroot |
External root on USB, with overlay migration and restore |
firewall |
Defaults, zones, forwardings, rules, redirects, ipsets, NAT |
mesh11sd |
802.11s mesh interfaces and the mesh11sd daemon |
network |
Globals, devices, interfaces, rules and routes |
node_exporter |
Prometheus node-exporter-lua and its listen settings |
pbr |
Policy-Based Routing service settings and policies |
system |
Hostname, description, timezone and logging |
wireguard |
Wireguard interfaces and peers, with key generation |
wireless |
Radios and interfaces, including 802.11r fast roaming |
-
The host group must be named
openwrt. Thegekmihesg.openwrtvars plugin only rewritesansible.builtin.*to its shell modules for hosts in a group with that exact name. Outside it, Ansible sends real Python modules to a device that has no Python and every task fails. See gekmihesg/ansible-openwrt. -
OpenWrt 24.10 replaced
opkgwithapk. Every role installs packages throughopkg, andgekmihesg.openwrtships noapkwrapper, so package installation fails on 24.10 and newer. The UCI configuration tasks themselves are unaffected. -
extrootrepartitions and reboots. Withextroot_enabled: trueand no extroot yet configured, the role runspartedandmkfs.ext4over the whole ofextroot_device(sdaby default), copies the overlay onto it and reboots the device. Everything on that disk is destroyed. The default isfalse. -
batmanandmesh11sdremove wpad packages. Both uninstall every variant listed in*_non_mesh_pkgsbefore installingwpad-mesh-wolfssl. On a device reached over Wi-Fi, that drops the connection. -
pbrmay replace dnsmasq with a snapshot build. If the installeddnsmasq-fullis older thanpbr_dnsmasq_full_required_versionand the release feed has nothing newer, the role removes dnsmasq and installsdnsmasq-full,libuboxandlibubusfrom the OpenWrt snapshot feed — mixing snapshot packages into a release install. -
extrootfetches two scripts from the OpenWrt wiki at run time and executes them, so what runs is whatever the wiki serves that day. -
Every role is a no-op until configured. All list and dictionary variables default to empty, so a role with no configuration installs its packages (where it has any) and changes nothing else.
Devices are defined in tests/inventory.yml, and their
variables in tests/group_vars/ and tests/host_vars/.
task provision # run tests/playbook.yml against the inventory
task lint # pre-commit over the whole collection
task build # build the collection tarballThere is no VM harness: OpenWrt roles need real hardware, so provision runs
against whatever tests/inventory.yml points at. The playbook reboots every
device when it finishes.
roles/batman/files/luci-proto-batman-adv.ipk is a prebuilt OpenWrt package
redistributed here, under its own upstream licence.
fLy0v3rH34d