Network configuration Puppet module
APACHE-2.0 License
This module takes a rather complex set of hiera data to manage network infrastructures on Network Manager based systems (eg: RHEL7). It supports:
This module manages the interface configuration files in /etc/sysconfig/network-scripts
, as well as starting and stopping interfaces.
You can choose just to use the Types and providers that this module exposes, network_interface
and ip_allocation
and wrap these into your own module. Or the puppet module can be used to define complex network infrastructures in Hiera.
The only officially supported OS for this module right now is RedHat/CentOS 7.0 - support for RHEL6 is limited and not very well tested at this time.
network_interface
network_interface { 'ens33':
ensure => 'present',
bootproto => 'static',
device => 'ens33',
ipv6init => 'yes',
netboot => 'yes',
onboot => 'yes',
type => 'Ethernet',
}
This type takes an interface name as a title and configures the interface in /etc/sysconfig/network-scripts/ifcfg-<name>
See the configuration parameter reference for a complete list of configurable parameters that this type accepts.
ip_allocation
ip_allocation { '192.168.193.3':
ensure => 'present',
gateway => '192.168.193.100',
interface => 'ens33',
prefix => '24',
}
This type takes an IP address as the resource title. Supported parameters are:
Parameter | Description |
---|---|
ensure |
present or absent
|
interface |
The interface name this allocation is assigned to |
prefix |
The prefix (CIDR notation) of the IP address |
netmask |
The netmask of the IP address (eg: 255.255.255.0) |
gateway |
The gateway for this IP allocation |
Note that only one of prefix
or netmask
should be used.
Multiple IP addresses bound to the same interface will be configured with their numerical identifier (eg: IPADDR0
, PREFIX0
, IPADDR1
, PREFIX1
, IPADDR2
, PREFIX2
...etc). The provider also ensures that when removing an IP allocation for an interface that all the numerical identifiers are re-sorted if there are gaps in the sequence, since Network Manager will not read beyond the first gap.
IP addresses are considered unique, therefore changing the interface
parameter will have the effect of moving the IP allocation from one interface to another
Network_config::Ifconfig[ens99]/Ip_allocation[10.7.6.10]/interface: interface changed 'ens39' to 'ens99'
ip_route
ip_route { '10.72.1.0/24':
ensure => 'present',
gateway => '10.72.1.1',
interface => 'ens33',
}
This type takes an CIDR address as the resource title. Supported parameters are:
Parameter | Description |
---|---|
ensure |
present or absent
|
interface |
The interface name this route is assigned to |
gateway |
The gateway for the static route |
|
There are two optional parameters which are the resources namevars, netmask
and address
- if these two attributes are not set then the CIDR range from the resource title is used to populate the netmask and address.
Both network_interface
and ip_allocation
are purgable resources, meaning they support the instances()
method. We recommend using the crayfishx/purge module as it offers more finite control over purging, for example, to purge all unmanaged IP allocations, except the loopback interface, you could do something like
purge { 'ip_allocation':
unless => [ 'interface', '==', 'lo' ],
}
For purging all interfaces and ip_allocations you can also set the purge_interfaces
and purge_ip_allocations
options on the network_config
class. When using these options, any interfaces with a name
or device
matching an entry in exclude_if
, plus any IP allocations with an interface
matching an entry in exclude_if
will not be purged. (NOTE: make sure you are running crayfishx/purge >= 1.1.0). As a further precaution, an ip_allocation of 127.0.0.1
will never be purged by the class.
The module is designed to get most of it's configuration from data lookups. To invoke the module, simply include it
class { 'network_config': }
Parameter | Description | Default |
---|---|---|
interfaces |
Interfaces to configure |
interfaces fact |
interface_names |
Mapping of interfaces to type names | n/a |
defaults |
Defaults for each interface type | n/a |
vlans |
VLAN specific configuration | n/a |
ifconfig |
Host specific interface configuration | n/a |
bonds |
Bond interfaces and specific configuration | {} |
bond_defaults |
Optional hash of default configuration for bond configuration | {} |
exclude_if |
List of interfaces to exclude from management, even if interfaces has them |
lo |
networkmanager |
True or false, is NetworkManager enabled (to be deprecated) | RHEL7 true, RHEL6 false |
purge_interfaces |
True or false, whether or not to purge non managed interfaces (this will completely remove the ifcfg- file for interfaces not being managed by Puppet. Any interface matching a device name of lo or a name of loopback will not be purged |
false |
purge_ip_allocations |
True or false, whether or not to purge unmanaged IP addresses, an IP address matching 127.0.0.1 or with the interface lo will not be purged |
false |
restart_service * |
Whether or not to restart the network service on change | true |
restart_interface * |
Whether or not to restart the affected network interface on change | false |
* only one of restart_interface or restart_service can be defined
network_config::interfaces
This setting is a list of interfaces that we want to configure on the system. If it is not set then the module will use the output of the interfaces
fact. To override this, we can give a comma separated list of the interfaces that we want to manage. Eg:
network_config::interfaces: eth0,eth1,eth2
Note that this is a comma separated string, with no spaces. Not an array.
network_config::interface_names
The first thing that should be configured are interface names. We define interface configuration parameters against interface types, that is, instead of saying eth0
, eth1
...etc, we assign friendly names to these interfaces and refer to them by the type of interface they are, eg: management. For each interface we want to manage we assign it a type, eg:
network_config::interface_names:
eth0: management
eth1: application
eth2: backup
interface_names is a meaningfull label only used within the context of hiera and puppet.
network_config::defaults
Now that we have our interface type names defined in interface_names
we can add some global defaults to each of these interface types. We have the opportunity to override these in specific circumstances, but things that are generally global such as domain, can be configured as defaults. Eg:
network_config::defaults:
management:
bootproto: "none"
defroute: "no"
dns1: 10.0.8.2
dns2: 10.0.8.3
dns3: 10.0.8.4
domain: enviatics.com
onboot: "yes"
backup:
bootproto: "none"
defroute: "no"
dns1: 10.0.0.2
dns2: 10.0.0.3
dns3: 10.0.0.4
domain: enviatics.com
interface_type: "Ethernet"
onboot: "yes"
application:
bootproto: "none"
defroute: "no"
dns1: 10.0.6.2
dns2: 10.0.6.3
dns3: 10.0.6.4
domain: app.enviatics.com
onboot: "yes"
See the configuration parameter appendix for a list of supported parameters.
network_config::vlans
This setting gives us specific control to add configuration or override defaults for different vlans. Eg:
network_config::vlans:
100:
prefix: 24
gateway: 10.0.8.1
200:
prefix: 32
gateway: 10.0.0.1
300:
prefix: 24
gateway: 10.0.6.3
Note that any configuration parameter can be overridden here for a specific vhost, eg:
network_config::vlans:
100:
prefix: 24
gateway: 10.0.8.1
domain: vlan_100.enviatics.com
network_config::ifconfig
The ifconfig
setting would normally be configured at the host level in your lookup hierarchy, and it's this parameter which ties together and inherits all of the above default settings. ifconfig
is a hash of interface types and configuration parameters, it accepts any configuration parameter as a host specific override, as well as vlan
to inherit configuration parameters from the VLAN is belongs to. A simple example would be:
network_config::ifconfig:
application:
ipaddr: 10.0.8.101
vlan: 100
The above configuration will get all the default configuration for a management interface type, the gateway and prefix parameters inherited from the assigned VLAN and we are specifying the IP address specific to this host.
Like the other options, you can override any configuration parameter at this level and it will take priority, eg:
network_config::ifconfig:
application:
ipaddr: 10.0.8.101
vlan: 100
gateway: 10.0.8.254
This will override the VLAN default and set the gateway to .254
The ipaddr
parameter can also take an array
network_config::ifconfig:
application:
ipaddr:
- 10.0.8.101
- 10.0.8.102
vlan: 100
In the above example we will end up with a configuration file that contains
IPADDR0=10.0.8.101
GATEWAY0=10.0.8.1
PREFIX0=24
IPADDR1=10.0.8.102
GATEWAY1=10.0.8.1
PREFIX1=24
Note that the PREFIX
and GATEWAY
in this example were automatically worked out, as they are inherited from the VLAN that the interface has been assigned to.
When evaluating the configuration, the module will prioritise duplicate settings top down in the following order (first has highest priority/win)
network_config::ifconfig
network_config::vlans
(if supplied to network_config::ifconfig
)network_config::bonds
(see below)network_config::defaults
for the specific type of interface being configured.If you need to bond multiple interfaces for a particular interface type you can follow much of the same procedure... firstly we create an additional network interface type for bond interface defaults, the name does not matter. Eg:
network_config::defaults
...
bond_interface:
bootproto: "none"
defroute: "no"
onboot: "yes"
Next we assign two interfaces that we want to be the bound interface slaves. We also define a new interface that will be our bond0
and we can give it an interface type like we did earlier, eg:
network_config::interface_names:
...
eth3: bond_interface
eth4: bond_interface
bond0: application
This will configure bond0
as an application interface inheriting all of our defaults from that type. We also have eth3
and eth4
configured with general bonding defaults.
The final step is to define which real interfaces are slaves of which bond interfaces, we do this with the bonds
parameter.
network_config::bonds:
bond0:
interfaces:
- eth3
- eth4
The above will make sure that eth3
and eth4
interfaces are configured as slaves of bond0
with
NAME=ens51
MASTER=bond0
SLAVE=yes
... as well as all the inherited configuration from the bond_interface
type.
The bonds
hash can also contain other bond specific configuration to apply to the bond interface (bond0
in our example). Eg:
network_config::bonds:
bond0:
bonding_opts: 'miimon=100 mode=1'
interfaces:
- eth3
- eth4
Shared configuration common to all bond interfaces maybe defined in the bond_defaults
hash
network_config::bond_defaults
bonding_opts: 'miimon=100 mode=1'
network_config::bonds:
bond0:
interfaces:
- eth3
- eth4
both configure in bond0
BONDING_OPTS=miimon=100 mode=1
Teaming can be configured very similar to bonding. First we need to define a network interface type with the defauts. Eg:
network_config::defaults
...
team_interface:
bootproto: "none"
defroute: "no"
onboot: "yes"
Next we assign two interfaces that we want to be the be in the team. We also define a new interface that will be our team0
and we can give it an interface type like we did earlier, eg:
network_config::interface_names:
...
eth3: team_interface
eth4: team_interface
team0: application
This will configure team0
as an application interface inheriting all of our defaults from that type. We also have eth3
and eth3
configured with general teaming defaults.
The final step is to define which real interfaces are members of which team interfaces, we do this with the teams
parameter.
network_config::teams:
team0:
interfaces:
eth3: {}
eth4: {}
The above will make sure that eth3
and eth4
interfaces are configured as members of team0
with
NAME=eth3
TEAM_MASTER=team0
DEVICETYPE=TeamPort
... aswell as all the inherited configuration from the team_interface
type.
The teams
hash can also contain other team specific configuration to apply to the team interface (team0
in our example). Eg:
network_config::teams:
team0:
team_config:
runner:
name: lacp
active: true
fast_rate: true
link_watch:
name: ethtool
interfaces:
eth3: {}
eth4: {}
Shared configuration common to all team interfaces maybe defined in the team_defaults
hash
network_config::team_defaults
team_config:
runner:
name: lacp
active: true
fast_rate: true
link_watch:
name: ethtool
network_config::teams:
team0:
interfaces:
eth3: {}
eth4: {}
both configure in team0
TEAM_CONFIG='{"runner":{"name":"lacp","active":true,"fast_rate":true},"link_watch":{"name":"ethtool"}}'
Teaming also allows interface specific settings defined in the team_port_config
Hash. Eg:
network_config::teams:
team0:
interfaces:
eth3:
team_port_config:
prio: 100
eth4: {}
This will configure for eth3
only
TEAM_PORT_CONFIG='{"prio":100}'
You can also specify team_port_config
in the interface types if you use the same options over multiple
interfaces.
Instead of specifiying the content of team_config
or team_port_config
as Hash they can also be defined
directly as a String containing json. In this case the String value will be used as-is and be written to
the file surounded with single quotes.
Parameter | NM configured option | |
---|---|---|
netmask | NETMASK | |
bootproto | BOOTPROTO | |
defroute | DEFROUTE | |
ipv4_failure_fatal | IPV4_FAILURE_FATAL | |
ipv6init | IPV6INIT | |
ipv6_autoconf | IPV6_AUTOCONF | |
ipv6_defroute | IPV6_DEFROUTE | |
ipv6_failure_fatal | IPV6_FAILURE_FATAL | |
uuid | UUID | |
onboot | ONBOOT | |
dns1 | DNS1 | |
dns2 | DNS2 | |
dns3 | DNS3 | |
domain | DOMAIN | |
hwaddr | HWADDR | |
ipv6_peerdns | IPV6_PEERDNS | |
ipv6_peerroutes | IPV6_PEERROUTES | |
zone | ZONE | |
type | TYPE | network_interface type param only |
interface_type | TYPE | Hiera config only |
device | DEVICE | |
bonding_opts | BONDING_OPTS | |
bonding_master | BONDING_MASTER | |
master | MASTER | |
slave | SLAVE | |
netboot | NETBOOT | |
nm_controlled | NM_CONTROLLED | |
peerdns | PEERDNS | |
gateway | GATEWAY | |
devicetype | DEVICETYPE | |
team_master | TEAM_MASTER | |
team_port_config | TEAM_PORT_CONFIG | |
team_config | TEAM_CONFIG |