← Ordo Artificum

ansible-tplink

Ansible collection for TP-Link switches

Eleven idempotent Ansible modules for managing TP-Link managed switches as infrastructure-as-code. Declare your VLAN layout, port settings, and QoS policy in YAML — the collection handles the rest.

Early release — lightly tested github.com/jfrancis42/ansible-tplink

New project — lightly tested

Tested against a small number of TL-SG108E (8-port) and TL-SG116E (16-port) switches. Compatibility with other TP-Link managed switch models is untested. The module interface may change without notice. Verify each operation on your hardware before use in production — especially VLAN changes on live switches.

What it is

TP-Link managed switches have no REST API, no SSH, and no Ansible connection plugin — their only configuration interface is a frameset-based web UI. ansible-tplink wraps the tplink-tool Python SDK to expose eleven fully idempotent Ansible modules that manage these switches the same way you would any other network device.

All modules support check mode (--check), report changed/unchanged state accurately, and are safe to run repeatedly. The collection runs locally on the Ansible control node (connection: local) — no agent or SSH access to the switch is required.

VLAN configuration, port settings, QoS, storm control, bandwidth limits, LAG groups, port mirroring, IGMP snooping, and loop prevention are all declaratively managed. Maintenance tasks — reboot, backup, restore, and factory reset — are also available.

Modules

Module What it manages
facts Gather switch facts (model, firmware, port count, MAC, uptime) into Ansible variables
system Description, static IP, netmask, gateway, DHCP mode, LED state
port Per-port enable/disable, speed/duplex, flow control — accepts a list of ports
trunk LAG/trunk groups — member ports and hash algorithm
mirror Port mirroring — source ports, destination port, direction
igmp IGMP snooping, report suppression, and loop prevention
qos QoS scheduling mode (port-based, 802.1p, DSCP, or combined)
bandwidth Per-port ingress and egress bandwidth limits in kbps — accepts a list of ports
storm Per-port storm control — broadcast/multicast/unknown-unicast rate limits
vlan 802.1Q VLAN configuration — tagged/untagged ports, PVIDs, VLAN names, MTU VLAN, port-based VLAN
maintenance Reboot, config backup to file, config restore from file, factory reset, cable diagnostics

Quick start

A minimal playbook that sets a description, configures all ports, and creates a two-VLAN layout with a trunk port:

---
- name: Configure access switch
  hosts: my-switch
  connection: local
  gather_facts: false
  tasks:
    - name: System settings
      jfrancis42.tplink.system:
        host: "{{ ansible_host }}"
        password: "{{ tplink_password }}"
        description: access-sw-1
        ip: 192.168.1.10
        netmask: 255.255.255.0
        gateway: 192.168.1.1
    - name: All ports enabled, auto speed
      jfrancis42.tplink.port:
        host: "{{ ansible_host }}"
        password: "{{ tplink_password }}"
        port: [1, 2, 3, 4, 5, 6, 7, 8]
        enabled: true
        speed: AUTO
    - name: Enable 802.1Q
      jfrancis42.tplink.vlan:
        host: "{{ ansible_host }}"
        password: "{{ tplink_password }}"
        vlan_mode: dot1q
        allow_mode_change: true
    - name: VLAN 1 — ports 1-7 access
      jfrancis42.tplink.vlan:
        host: "{{ ansible_host }}"
        password: "{{ tplink_password }}"
        vlan_mode: dot1q
        vlan_id: 1
        name: Default
        tagged_ports: [8]
        untagged_ports: [1, 2, 3, 4, 5, 6, 7]
        state: present
    - name: VLAN 10 — IoT access on port 4, trunk on port 8
      jfrancis42.tplink.vlan:
        host: "{{ ansible_host }}"
        password: "{{ tplink_password }}"
        vlan_mode: dot1q
        vlan_id: 10
        name: IoT
        tagged_ports: [8]
        untagged_ports: [4]
        pvid: 10
        state: present

Installation

Install from Ansible Galaxy:

ansible-galaxy collection install jfrancis42.tplink
# Requires: tplink-tool SDK (tplink_switch.py) on the Python path
# Requires: Python 3.8+, requests library

The collection depends on the tplink-tool SDK. Place tplink_switch.py anywhere on your Python path, or drop it into the collection's plugins/module_utils/ directory.

All modules use connection: local — set this at the play level or in your inventory's [group:vars]. The host and password parameters are passed directly to each module.