Deploy Network Configuration

This role manages multi-VLAN network configuration across heterogeneous systems in the homelab environment.

ARA Ansible Bash Centreon Debian Docker Grafana Graylog

Deploy Network Configuration Role

Overview

This role manages multi-VLAN network configuration across heterogeneous systems in the homelab environment. It deploys routing tables, NetworkManager configurations for RedHat systems, NetworkManager dispatcher scripts for Docker servers, custom routing scripts with systemd services for OpenMediaVault, and /etc/network/interfaces configuration for Proxmox and ZoneMinder. The role includes comprehensive safety features including confirmation prompts, check mode support, configuration backups, and connectivity validation to prevent accidental network disruption.

Purpose

  • Multi-VLAN Management: Configure complex network setups with multiple VLANs
  • OS-Specific Configuration: Support RedHat NetworkManager and Debian ifupdown
  • Routing Tables: Configure custom routing tables for policy-based routing
  • Dispatcher Scripts: NetworkManager event-driven network configuration
  • Configuration Validation: Prevent drift from manual changes
  • Safe Deployment: Confirmation prompts and connectivity validation
  • Backup Integration: Automatic backup before changes

Requirements

  • Ansible 2.9 or higher
  • Target systems: RedHat/Rocky Linux or Debian/Ubuntu
  • Root or sudo privileges
  • Console or IPMI access (strongly recommended)
  • Working network connectivity before first run
  • Backup of existing network configuration
  • Manual initial network setup completed

Important: Initial Setup Required

CRITICAL: This role is designed for configuration validation and drift prevention, not initial network setup.

Why manual setup first?

  1. Ansible requires network connectivity to run
  2. Network configuration changes could break the Ansible connection
  3. Manual setup ensures a known working state

This role’s purpose: Maintain and validate network configuration after manual bootstrap.

What is Policy-Based Routing?

Policy-based routing allows routing decisions based on criteria beyond destination address:

Standard routing:

Packet to 192.168.x.x → Check routing table → Use default gateway

Policy-based routing:

Packet from VLAN10 → Use routing table 100 (mgmt gateway)
Packet from VLAN12 → Use routing table 101 (servers gateway)

Use cases:

  • Multi-homed servers (multiple network interfaces)
  • VLAN segmentation with separate gateways
  • Load balancing across interfaces
  • Source-based routing decisions

Role Variables

Optional Variables

VariableDefaultDescription
deploy_network_configuration_require_confirmationtruePrompt before changes
deploy_network_configuration_rt_tablesSee defaultsRouting table definitions
deploy_network_configuration_interfacesundefinedPer-host interface config
deploy_network_configuration_nm_service_nameNetworkManagerNetworkManager service
deploy_network_configuration_nm_connections_dir/etc/NetworkManager/system-connectionsConnection files path
deploy_network_configuration_nm_dispatcher_dir/etc/NetworkManager/dispatcher.dDispatcher scripts path
deploy_network_configuration_interfaces_file/etc/network/interfacesDebian interfaces file
deploy_network_configuration_networking_service_namenetworkingDebian networking service
deploy_network_configuration_rt_tables_file_default/usr/share/iproute2/rt_tablesRouting tables file
deploy_network_configuration_rt_tables_file_omv/etc/iproute2/rt_tablesOMV routing tables file
deploy_network_configuration_omv_routing_script_path/usr/local/bin/setup-omv-routing.shOMV routing script
deploy_network_configuration_omv_routing_service_nameomv-routing.serviceOMV systemd service

Variable Details

deploy_network_configuration_require_confirmation

Whether to prompt for confirmation before applying network changes.

Default: true (safe mode, prompts before changes)

Disable for automation:

deploy_network_configuration_require_confirmation: false

Prompt shown:

========================================
WARNING: Network Configuration Changes
========================================

About to modify network configuration on: hostname

This could potentially disconnect your Ansible connection.

Recommendations:
- Ensure you have console/IPMI access available
- Review changes with --check mode first
- Have a rollback plan ready

Press Ctrl+C and then 'A' to abort
Press ENTER to continue
========================================

Recommended: Keep enabled unless running in CI/CD with known-good config

deploy_network_configuration_rt_tables

Routing table definitions for policy-based routing.

Default:

deploy_network_configuration_rt_tables:
  - id: 100
    name: mgmt
  - id: 101
    name: servers

Custom tables:

deploy_network_configuration_rt_tables:
  - id: 10
    name: vlan10
  - id: 20
    name: vlan20
  - id: 30
    name: vlan30

Result: Entries added to routing tables file:

# Custom routing tables for policy-based routing
100 mgmt
101 servers

Usage: Enables ip route add ... table mgmt commands

deploy_network_configuration_interfaces

Per-host interface configuration variable.

Important: This variable is not defined by default. Each host must define its own configuration.

Example (in host_vars/docker.yml):

deploy_network_configuration_interfaces:
  vlan10:
    ip: 192.168.x.x
    gateway: 192.168.x.x
  vlan12:
    ip: 192.168.x.x
    gateway: 192.168.x.x

Role behavior: If deploy_network_configuration_interfaces is undefined, role skips that host.

Purpose: Signal to role that this host has network configuration to deploy.

Dependencies

No Ansible role dependencies, but requires:

  • Working network connectivity (manual initial setup)
  • Console or IPMI access for recovery
  • Configuration files prepared (see below)

Often used with:

  • nas_mount or nas_mount_systemd: Mount NAS before network config
  • deploy_ssh_keys: Ensure SSH access before network changes

Example Playbook

Basic Usage (All Systems)

---
- name: Deploy Network Configuration
  hosts: all
  become: true

  roles:
    - deploy_network_configuration

With Confirmation Disabled (CI/CD)

---
- name: Deploy Network Config (Automated)
  hosts: all
  become: true

  vars:
    deploy_network_configuration_require_confirmation: false

  roles:
    - deploy_network_configuration

Check Mode First (Safe Practice)

# Preview changes without applying
ansible-playbook deploy_network.yml --check --diff

# Apply after reviewing
ansible-playbook deploy_network.yml

Specific Hosts Only

---
- name: Deploy Network Config to Docker Host
  hosts: docker
  become: true

  roles:
    - deploy_network_configuration

What This Role Does

1. Display Confirmation Prompt (if enabled)

Shows warning with recommendations.

When: deploy_network_configuration_require_confirmation: true (default)

Skipped if:

  • Confirmation disabled
  • Host doesn’t have deploy_network_configuration_interfaces defined

2. Deploy Routing Tables Configuration

File: /usr/share/iproute2/rt_tables (most) or /etc/iproute2/rt_tables (OMV)

Content added:

# Custom routing tables for policy-based routing
100 mgmt
101 servers

Purpose: Enables named routing tables for policy-based routing

3. Deploy OS-Specific Network Configuration

RedHat NetworkManager (Centreon, Docker, Grafana, Graylog, etc.):

  • Copies .nmconnection files to /etc/NetworkManager/system-connections/
  • Sets permissions: 0600 (root only, security requirement)
  • Copies dispatcher scripts to /etc/NetworkManager/dispatcher.d/
  • Sets permissions: 0755 (executable)
  • Reloads or restarts NetworkManager

Debian NetworkManager (OpenMediaVault):

  • Deploys custom routing script to /usr/local/bin/setup-omv-routing.sh
  • Creates systemd service: omv-routing.service
  • Service runs after network-online.target
  • Enables and starts service
  • Configures nginx to bind web interface to management VLAN IP
  • Preserves localhost bindings for local access
  • Restarts nginx when configuration changes

Debian ifupdown (Proxmox, ZoneMinder):

  • Deploys /etc/network/interfaces from template
  • Creates backup of existing configuration first
  • Restarts networking service

4. Validate Network Connectivity

After configuration changes:

  • Waits up to 60 seconds for network to stabilize
  • Tests Ansible connectivity
  • Reports success or failure

If validation fails: You have console access to troubleshoot

Supported System Configurations

RedHat/Rocky Linux (NetworkManager)

Hosts: Centreon, Docker, Grafana, Graylog, Graylog-Data1

Configuration files required:

  • files/<hostname>/*.nmconnection - NetworkManager connection files
  • files/<hostname>/dispatcher.d/* - NetworkManager dispatcher scripts

Example directory structure:

files/
└── docker/
    ├── vlan10-enp2s0.nmconnection
    ├── vlan12-enp2s0.nmconnection
    └── dispatcher.d/
        └── 99-custom-routes

Connection file format (.nmconnection):

[connection]
id=vlan10-enp2s0
type=vlan
interface-name=enp2s0.10

[vlan]
parent=enp2s0
id=10

[ipv4]
method=manual
address1=192.168.x.x/24
gateway=192.168.x.x
route1=192.168.x.x/24,0.0.0.0,100

Key points:

  • Permissions: 0600 (NetworkManager requirement)
  • Owner: root:root
  • Format: INI-style configuration

Debian with NetworkManager (OpenMediaVault)

Hosts: prxmx-omv

Configuration files required:

  • templates/<hostname>/setup-omv-routing.sh.j2 - Custom routing script template
  • templates/<hostname>/omv-routing.service.j2 - Systemd service template

Script example (setup-omv-routing.sh.j2):

#!/bin/bash
# Setup policy-based routing for OMV

# Add routes to mgmt table
ip route add default via 192.168.x.x table mgmt
ip rule add from 192.168.x.x/24 table mgmt

# Add routes to servers table
ip route add default via 192.168.x.x table servers
ip rule add from 192.168.x.x/24 table servers

Systemd service: omv-routing.service

  • Runs once at boot
  • After: network-online.target
  • Type: oneshot
  • RemainAfterExit: yes

Nginx web interface binding: The role automatically configures OpenMediaVault’s nginx web interface to bind only to:

  • Management VLAN IP (e.g., 192.168.x.x:80 and 192.168.x.x:443)
  • Localhost (127.0.0.1:80 and 127.0.0.1:443)

This enhances security by preventing web interface access from other VLANs. The configuration:

  • Modifies /etc/nginx/sites-enabled/openmediavault-webgui
  • Handles both wildcard (*) and existing IP configurations
  • Preserves localhost bindings for local access
  • Automatically restarts nginx when changes are made
  • Is idempotent (safe to run multiple times)

Debian with ifupdown (Proxmox, ZoneMinder)

Hosts: Proxmox, ZoneMinder

Template required:

  • templates/<hostname>/interfaces.j2

Template example:

# /etc/network/interfaces

auto lo
iface lo inet loopback

# VLAN10 - Management
auto enp1s0.10
iface enp1s0.10 inet static
    address 192.168.x.x/24
    gateway 192.168.x.x
    vlan-raw-device enp1s0
    post-up ip route add 192.168.x.x/24 dev enp1s0.10 table mgmt
    post-up ip rule add from 192.168.x.x table mgmt

# VLAN12 - Servers
auto enp1s0.12
iface enp1s0.12 inet static
    address 192.168.x.x/24
    vlan-raw-device enp1s0
    post-up ip route add default via 192.168.x.x table servers
    post-up ip rule add from 192.168.x.x table servers

NetworkManager Dispatcher Scripts

Purpose: Run commands when NetworkManager events occur

Event types:

  • up: Interface brought up
  • down: Interface brought down
  • pre-up: Before interface comes up
  • post-down: After interface goes down

Script naming: Scripts run alphabetically (use numeric prefix)

  • 10-script: Runs early
  • 99-script: Runs late

Example dispatcher script:

#!/bin/bash
# /etc/NetworkManager/dispatcher.d/99-custom-routes

# Only run on interface up events
[ "$2" != "up" ] && exit 0

# Configure policy-based routing
if [ "$1" = "enp2s0.10" ]; then
    ip route add default via 192.168.x.x table mgmt
    ip rule add from 192.168.x.x/24 table mgmt
fi

Permissions: 0755 (executable)

File Locations

System TypeConfiguration FilePurpose
RedHat/etc/NetworkManager/system-connections/*.nmconnectionConnection definitions
RedHat/etc/NetworkManager/dispatcher.d/*Event scripts
OMV/usr/local/bin/setup-omv-routing.shCustom routing
OMV/etc/systemd/system/omv-routing.serviceSystemd service
OMV/etc/nginx/sites-enabled/openmediavault-webguiNginx web interface config
Proxmox/ZM/etc/network/interfacesInterface config
All/usr/share/iproute2/rt_tablesRouting tables
OMV/etc/iproute2/rt_tablesRouting tables (OMV)

Configuration Workflow

Recommended process:

  1. Manual initial setup: Configure network during OS installation
  2. Backup configuration: Save working config files from system
  3. Add to role: Place files in role’s files/ or templates/
  4. Test with —check: Preview changes before applying
    ansible-playbook deploy_network.yml --check --diff
    
  5. Deploy role: Apply configuration
  6. Maintain: Role prevents drift from manual changes

Security Considerations

  • Confirmation Prompts: Prevent accidental network disruption
  • File Permissions: NetworkManager files must be 0600 (sensitive)
  • Dispatcher Scripts: Must be 0755 (executable)
  • Backup Before Changes: Automatic backup of existing config
  • Console Access Recommended: In case network connection lost
  • Check Mode Support: Preview changes safely
  • Validation: Connectivity tested after changes

Tags

This role does not define any tags. Use playbook-level tags if needed:

- hosts: all
  roles:
    - deploy_network_configuration
  tags:
    - network
    - infrastructure
    - routing

Notes

  • Role runs on target systems (not localhost)
  • become: true required for network configuration
  • Skips hosts without deploy_network_configuration_interfaces defined
  • NetworkManager systems reload configuration without full restart
  • Debian ifupdown systems restart networking service (brief interruption)
  • Confirmation prompt appears per-host if enabled
  • Compatible with RedHat, Rocky Linux, Debian, Ubuntu
  • Manual initial setup required (Ansible needs connectivity)
  • Configuration files must be prepared in role directories

Troubleshooting

Connection lost after running role

Symptom: Ansible loses connection to host

Immediate action:

  1. Access via console/IPMI
  2. Check interface status: ip addr, ip link
  3. Check routing: ip route show table all
  4. Restore from backup if needed

For NetworkManager systems:

# Check NetworkManager status
systemctl status NetworkManager

# Restart NetworkManager
systemctl restart NetworkManager

# Check connection files
nmcli connection show

# Activate connection
nmcli connection up vlan10-enp2s0

For ifupdown systems:

# Check interface status
ip addr show

# Bring interface up
ifup enp1s0.10

# Restore from backup
cp /etc/network/interfaces.backup /etc/network/interfaces
systemctl restart networking

NetworkManager connection file not applied

Symptom: Changes not taking effect

Check permissions:

ls -la /etc/NetworkManager/system-connections/

# Should be: -rw------- root root (0600)

Fix permissions:

chmod 0600 /etc/NetworkManager/system-connections/*.nmconnection

Reload NetworkManager:

systemctl reload NetworkManager
# Or
nmcli connection reload

Dispatcher script not executing

Symptom: Routes not added after network up

Check permissions:

ls -la /etc/NetworkManager/dispatcher.d/

# Should be: -rwxr-xr-x root root (0755)

Fix permissions:

chmod 0755 /etc/NetworkManager/dispatcher.d/*

Test script manually:

# Run dispatcher script manually
/etc/NetworkManager/dispatcher.d/99-custom-routes enp2s0.10 up

Check logs:

journalctl -u NetworkManager -f
# Watch for dispatcher events

Routing table entries not added

Symptom: ip route show table mgmt returns empty

Check rt_tables file:

cat /usr/share/iproute2/rt_tables | grep mgmt

# Should show: 100 mgmt

Check routing rules:

ip rule show

# Should see entries like:
# from 192.168.x.x/24 lookup mgmt

Add manually for testing:

ip route add default via 192.168.x.x table mgmt
ip rule add from 192.168.x.x/24 table mgmt

Validation fails after deployment

Symptom: Role reports validation failure

Causes:

  • Network not fully up yet (wait longer)
  • Configuration error (wrong IP/gateway)
  • Firewall blocking connectivity

Manual validation:

# From affected host
ping 192.168.x.x  # Gateway
ping 8.8.8.8       # Internet

# Check connectivity to Ansible controller
nc -zv ansible-controller-ip 22

Testing the Role

Preview Changes (Safe)

# Check mode with diff
ansible-playbook deploy_network.yml --check --diff --limit docker

# Shows what would change without applying

Verify Configuration Files

After role runs:

# NetworkManager systems
ls -la /etc/NetworkManager/system-connections/
nmcli connection show

# Debian ifupdown systems
cat /etc/network/interfaces

# Routing tables
cat /usr/share/iproute2/rt_tables
ip route show table all

Test Network Connectivity

# Check interfaces
ip addr show

# Check routing
ip route show
ip route show table mgmt
ip route show table servers

# Check rules
ip rule show

# Test connectivity
ping 192.168.x.x
ping 8.8.8.8

Best Practices

  1. Always use —check first: Preview changes before applying
  2. Maintain console access: Have IPMI/console ready during changes
  3. Backup configurations: Role creates backups automatically
  4. Test on non-critical hosts first: Validate on test systems
  5. Document changes: Keep notes on network design
  6. Version control: Store configuration files in git
  7. Manual initial setup: Bootstrap connectivity before Ansible
  8. Maintenance windows: Apply during scheduled downtime
  9. Have rollback plan: Know how to restore from backup
  10. Validate after changes: Ensure connectivity restored

Common Network Scenarios

Scenario 1: Docker Host with VLANs

Requirements:

  • VLAN10: Management (192.168.x.x/24)
  • VLAN12: Servers (192.168.x.x/24)
  • Policy-based routing: Each VLAN uses own gateway

Files needed:

  • files/docker/vlan10-enp2s0.nmconnection
  • files/docker/vlan12-enp2s0.nmconnection
  • files/docker/dispatcher.d/99-routing

Scenario 2: Proxmox with Multiple Interfaces

Requirements:

  • VLAN10: Management
  • VLAN12: VM network
  • VLAN14: Storage network

Template needed:

  • templates/proxmox/interfaces.j2

Scenario 3: OpenMediaVault NAS

Requirements:

  • Multiple network interfaces for different VLANs
  • Custom routing to ensure management via VLAN10
  • Storage access via VLAN12
  • Web interface accessible only from management VLAN

Files needed:

  • templates/prxmx-omv/setup-omv-routing.sh.j2
  • templates/prxmx-omv/omv-routing.service.j2

Automatic configuration:

  • Nginx web interface binds to management VLAN IP only
  • Localhost access preserved for local management

This role is often used with:

  • nas_mount: Mount NAS before network changes
  • nas_mount_systemd: Mount NAS with systemd
  • deploy_ssh_keys: Ensure SSH access maintained
  • System installation roles: Initial setup after OS install

Recovery Procedures

Complete Network Failure

  1. Access via console/IPMI
  2. Identify issue: Check logs, interface status
  3. Restore from backup:
# NetworkManager
cp /etc/NetworkManager/system-connections/*.backup /etc/NetworkManager/system-connections/
systemctl restart NetworkManager

# ifupdown
cp /etc/network/interfaces.backup /etc/network/interfaces
systemctl restart networking
  1. Manual configuration: Reconfigure manually if needed
  2. Update role files: Fix configuration in role before re-running

License

MIT

Author

Created for homelab infrastructure management.