Netplan Configuration
Overview
OmniCore can automatically configure network interfaces on deployed VMs using netplan. This is useful for:
- Setting up the primary management interface (eth0)
- Adding secondary interfaces for public IPs, peering connections, or dedicated traffic
- Configuring static routes for specific destinations
Enabling Netplan Configuration
To enable automatic netplan configuration for a host, add the netplan_config variable pointing to a Jinja2 template in your group_vars folder:
dra:
hosts:
<hostname>:
ansible_host: 10.0.1.100
gateway: 10.0.1.1
netplan_config: netplan.yaml.j2
The template will be sourced from hosts/<customer>/group_vars/netplan.yaml.j2.
Template Reference
Here is the complete netplan.yaml.j2 template with comments explaining each section:
network:
version: 2
ethernets:
# Primary interface - uses ansible_host and gateway from inventory
eth0:
addresses:
- "{{ ansible_host }}/{{ mask_cidr | default(24) }}"
nameservers:
addresses:
{% if 'dns' in group_names %}
# If this host IS a DNS server, use external DNS to avoid circular dependency
- 8.8.8.8
{% else %}
# Otherwise, use DNS servers from the 'dns' group in inventory
{% for dns_host in groups['dns'] | default([]) %}
- {{ hostvars[dns_host]['ansible_host'] }}
{% endfor %}
{% endif %}
search:
- slice
routes:
- to: "default"
via: "{{ gateway }}"
{% if secondary_ips is defined %}
# Secondary interfaces - loop through secondary_ips dict from inventory
# Interface naming: ens19, ens20, ens21... (18 + loop.index)
{% for nic_name, nic_config in secondary_ips.items() %}
ens{{ 18 + loop.index }}:
addresses:
- "{{ nic_config.ip_address }}/{{ mask_cidr | default(24) }}"
{% if nic_config.routes is defined %}
# Static routes for this interface - each route uses this interface's gateway
routes:
{% for route in nic_config.routes %}
- to: "{{ route }}"
via: "{{ nic_config.gateway }}"
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
Key points:
ansible_hostandgatewaycome from the host's inventory entry- DNS servers are dynamically pulled from hosts in the
dnsgroup - Secondary interfaces are named
ens19,ens20, etc. to match Proxmox NIC naming - Each secondary IP can have its own gateway and static routes
Primary Interface Configuration
The primary interface (eth0) is configured automatically using:
ansible_host- The IP addressgateway- The default gatewaymask_cidr- Network mask (defaults to 24)
DNS servers are automatically set to:
- Hosts in the
dnsgroup (uses theiransible_hostIPs) - Falls back to
8.8.8.8if the host is itself a DNS server
Secondary Interfaces
For hosts requiring additional network interfaces (public IPs, peering, etc.), use the secondary_ips configuration.
Schema
secondary_ips:
<logical_name>:
ip_address: <ip_address>
gateway: <gateway_ip>
host_vm_network: <proxmox_bridge>
vlanid: <vlan_id>
routes: # Optional - static routes via this interface
- '<destination_cidr>'
- '<destination_cidr>'
Interface Naming
Secondary interfaces are automatically named using Ubuntu's predictable naming scheme:
- First secondary interface:
ens19 - Second secondary interface:
ens20 - Third secondary interface:
ens21 - And so on...
This matches the interface names assigned by Proxmox when adding additional NICs to a VM.
Example Configuration
dra:
hosts:
<hostname>:
ansible_host: 10.0.1.100
gateway: 10.0.1.1
host_vm_network: "ovsbr1"
vlanid: "100"
netplan_config: netplan.yaml.j2
secondary_ips:
public_ip:
ip_address: 192.0.2.50
gateway: 192.0.2.1
host_vm_network: "vmbr0"
vlanid: "200"
routes:
- '198.51.100.0/24'
- '203.0.113.0/24'
peering_ip:
ip_address: 172.16.50.10
gateway: 172.16.50.1
host_vm_network: "ovsbr2"
vlanid: "300"
routes:
- '172.17.0.0/16'
Generated Netplan Output
The above configuration generates:
network:
version: 2
ethernets:
eth0:
addresses:
- "10.0.1.100/24"
nameservers:
addresses:
- 10.0.1.53
search:
- slice
routes:
- to: "default"
via: "10.0.1.1"
ens19:
addresses:
- "192.0.2.50/24"
routes:
- to: "198.51.100.0/24"
via: "192.0.2.1"
- to: "203.0.113.0/24"
via: "192.0.2.1"
ens20:
addresses:
- "172.16.50.10/24"
routes:
- to: "172.17.0.0/16"
via: "172.16.50.1"
Proxmox Integration
When using the proxmox.yml playbook, secondary NICs are automatically created on the VM:
- New VMs: Secondary NICs are added during initial provisioning
- Existing VMs: Secondary NICs are added and the VM is rebooted to apply changes
The Proxmox configuration uses:
host_vm_network- The bridge to attach the NIC tovlanid- VLAN tag for the interface
How It Works
- Variables from hosts file are passed to the Jinja2 template
- Template renders to
/etc/netplan/01-netcfg.yaml - Any existing netplan configs are removed to prevent conflicts
netplan applyactivates the configuration- IP addresses are verified with
ip addr show
Common Use Cases
Diameter Edge Agent (DEA) with Public IP
<hostname>:
ansible_host: 10.0.1.100 # Internal management IP
gateway: 10.0.1.1
netplan_config: netplan.yaml.j2
secondary_ips:
diameter_roaming:
ip_address: 192.0.2.50 # Public IP for roaming partners
gateway: 192.0.2.1
host_vm_network: "vmbr0"
vlanid: "200"
routes:
- '198.51.100.0/24' # Roaming partner network
PGW with S5/S8 Interface
<hostname>:
ansible_host: 10.0.2.20 # Internal IP
gateway: 10.0.2.1
netplan_config: netplan.yaml.j2
secondary_ips:
s5s8_interface:
ip_address: 203.0.113.17 # Public S5/S8 IP
gateway: 203.0.113.1
host_vm_network: "vmbr0"
vlanid: "50"
Multi-homed Server with Separate Management and Data Networks
<hostname>:
ansible_host: 10.0.1.100 # Management network
gateway: 10.0.1.1
netplan_config: netplan.yaml.j2
secondary_ips:
data_network:
ip_address: 10.0.2.100 # Data network
gateway: 10.0.2.1
host_vm_network: "ovsbr2"
vlanid: "200"
backup_network:
ip_address: 10.0.3.100 # Backup network
gateway: 10.0.3.1
host_vm_network: "ovsbr3"
vlanid: "300"
Referencing Secondary IPs in Templates
You can reference secondary IP addresses in other Jinja2 templates and configuration files.
On the Same Host
When configuring a service on the same host that has secondary IPs, you can reference directly or use inventory_hostname:
# Reference directly (simplest)
{{ secondary_ips.diameter_public_ip.ip_address }}
# Or explicitly via inventory_hostname (same result)
{{ hostvars[inventory_hostname]['secondary_ips']['diameter_public_ip']['ip_address'] }}
# Access other properties
{{ secondary_ips.diameter_public_ip.gateway }}
{{ secondary_ips.diameter_public_ip.vlanid }}
From Another Host
When you need to reference a different host's secondary IP (e.g., configuring a peer connection), use hostvars with the target hostname:
# Reference first host in dra group
{{ hostvars[groups['dra'][0]]['secondary_ips']['diameter_public_ip']['ip_address'] }}
# Loop through all DRA hosts and get their public IPs
{% for host in groups['dra'] %}
{% if hostvars[host]['secondary_ips'] is defined %}
- {{ hostvars[host]['secondary_ips']['diameter_public_ip']['ip_address'] }}
{% endif %}
{% endfor %}
Example: DRA Peer Configuration
Configure a diameter peer to bind to its own public IP:
# In dra_config.yaml.j2 - use inventory_hostname for the current host
peers:
- name: external_peer
# Bind to this host's public diameter IP
local_ip: {{ hostvars[inventory_hostname]['secondary_ips']['diameter_public_ip']['ip_address'] }}
remote_ip: 198.51.100.50
port: 3868
Checking if Secondary IPs Exist
Always check if the variable exists before using it:
{% if secondary_ips is defined and secondary_ips.diameter_public_ip is defined %}
public_ip: {{ secondary_ips.diameter_public_ip.ip_address }}
{% else %}
public_ip: {{ ansible_host }}
{% endif %}
Troubleshooting
Verify Interface Names
SSH to the VM and check interface names:
ip link show
Expected output for a VM with two secondary interfaces:
1: lo: <LOOPBACK,UP,LOWER_UP> ...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
3: ens19: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
4: ens20: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
Check Netplan Configuration
cat /etc/netplan/01-netcfg.yaml
Apply Netplan Manually
netplan apply
Debug Netplan
netplan --debug apply
Verify Routes
ip route show
Related Documentation
- Hosts File Configuration - Host inventory setup
- Proxmox VM/LXC Deployment - VM provisioning
- Configuration Reference - All configuration variables