├── .travis.yml ├── README.md ├── defaults └── main.yml ├── meta └── main.yml ├── tasks ├── debian.yml ├── main.yml ├── redhat.yml └── restartscript.yml ├── templates ├── Debian_bond_options.j2 ├── Debian_bridge_options.j2 ├── Debian_ipv4_config.j2 ├── Debian_ipv6_config.j2 ├── Debian_resolvconf.j2 ├── RedHat_bond_options.j2 ├── RedHat_generic_options.j2 ├── RedHat_ipv6_options.j2 ├── RedHat_vlan_options.j2 ├── bond_Debian.j2 ├── bond_RedHat.j2 ├── bond_slave_Debian.j2 ├── bond_slave_RedHat.j2 ├── bridge_Debian.j2 ├── bridge_RedHat.j2 ├── bridge_port_Debian.j2 ├── bridge_port_RedHat.j2 ├── ethernet_Debian.j2 ├── ethernet_RedHat.j2 ├── restartscript.j2 ├── route_Debian.j2 └── route_RedHat.j2 ├── tests ├── Dockerfile.centos-7 ├── Dockerfile.ubuntu-14.04 ├── Dockerfile.ubuntu-16.04 └── test.yml └── vars ├── Debian.yml ├── RedHat.yml └── main.yml /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: required 3 | 4 | env: 5 | - distribution: centos 6 | version: 7 7 | init: /usr/lib/systemd/systemd 8 | run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" 9 | - distribution: ubuntu 10 | version: 16.04 11 | init: /sbin/init 12 | run_opts: "" 13 | - distribution: ubuntu 14 | version: 14.04 15 | init: /sbin/init 16 | run_opts: "" 17 | 18 | services: 19 | - docker 20 | 21 | before_install: 22 | # - sudo apt-get update 23 | # Pull container 24 | - 'sudo docker pull ${distribution}:${version}' 25 | # Customize container 26 | - 'sudo docker build --rm=true --file=tests/Dockerfile.${distribution}-${version} --tag=${distribution}-${version}:ansible tests' 27 | 28 | script: 29 | - container_id=$(mktemp) 30 | # Run container in detached state 31 | - 'sudo docker run --privileged --detach --volume="${PWD}":/etc/ansible/roles/role_under_test:ro ${run_opts} ${distribution}-${version}:ansible "${init}" > "${container_id}"' 32 | 33 | # Ansible syntax check. 34 | - 'sudo docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml --syntax-check' 35 | 36 | # Test role. 37 | - 'sudo docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml' 38 | 39 | # Test role idempotence. 40 | # - > 41 | # sudo docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml 42 | # | grep -q 'changed=0.*failed=0' 43 | # && (echo 'Idempotence test: pass' && exit 0) 44 | # || (echo 'Idempotence test: fail' && exit 1) 45 | # Clean up 46 | - 'sudo docker stop "$(cat ${container_id})"' 47 | 48 | notifications: 49 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | network_interface 2 | ================= 3 | 4 | _WARNING: This role can be dangerous to use. If you lose network connectivity 5 | to your target host by incorrectly configuring your networking, you may be 6 | unable to recover without physical access to the machine._ 7 | 8 | This roles enables users to configure various network components on target 9 | machines. The role can be used to configure: 10 | 11 | - Ethernet interfaces 12 | - Bridge interfaces 13 | - Bonded interfaces 14 | - VLAN tagged interfaces 15 | - Network routes 16 | 17 | Requirements 18 | ------------ 19 | 20 | This role requires Ansible 1.4 or higher, and platform requirements are listed 21 | in the metadata file. 22 | 23 | Role Variables 24 | -------------- 25 | 26 | The variables that can be passed to this role and a brief description about 27 | them are as follows: 28 | 29 | | Variable | Required | Default | Comments | 30 | |-----------------------|----------|-----------|---------| 31 | | `network_ether_interfaces` | No | `[]` | The list of ethernet interfaces to be added to the system. | 32 | | `network_bridge_interfaces` | No | `[]` | The list of bridge interfaces to be added to the system. | 33 | | `network_bond_interfaces` | No | `[]` | The list of bonded interfaces to be added to the system. | 34 | | `network_vlan_interfaces` | No | `[]` | The list of vlan interfaces to be added to the system. | 35 | 36 | 37 | The different types of interfaces can be configured with following variables: 38 | 39 | ### Ethernet 40 | | Variable | OS | Is Required | 41 | | ----------- | ------ | ----------------- | 42 | | device | * | Yes | 43 | | type | RedHat | Optional | 44 | | _ADDR VARS_ | * | - | 45 | 46 | ### Bond 47 | | Variable | OS | Is Required | 48 | | ------------ | ------ | ----------------- | 49 | | device | * | Yes | 50 | | bond\_mode | * | Yes | 51 | | bond\_slaves | Debian | Yes | 52 | | bond\_slaves | RedHat | For Auto Config | 53 | | type | RedHat | For Manual Config | 54 | | _BOND VARS_ | * | - | 55 | 56 | ### Bond Slave (manual config) 57 | | Variable | OS | Is Required | 58 | | ----------- | ------ | ----------- | 59 | | device | * | Yes | 60 | | master | * | Yes | 61 | | type | RedHat | Optional | 62 | 63 | ### Bridge 64 | | Variable | OS | Is Required | 65 | | ------------- | ------ | ----------------- | 66 | | device | * | Yes | 67 | | bridge\_ports | * | Optional | 68 | | type | RedHat | For Manual Config | 69 | | ? | Debian | For Manual Config | 70 | | _BRIDGE VARS_ | * | - | 71 | 72 | ### Bridge Port (manual config) 73 | | Variable | OS | Is Required | 74 | | ----------- | ------ | ----------------- | 75 | | device | * | Yes | 76 | | bridge | RedHat | For Manual Config | 77 | | type | RedHat | Optional | 78 | 79 | ### VLAN 80 | | Variable | OS | Is Required | 81 | | ------------- | ------ | ----------------- | 82 | | device | * | Yes | 83 | | vlan | Redhat | For Manual Config | 84 | | vlan\_physdev | RedHat | Optional | 85 | | vlan\_id | RedHat | Optional | 86 | | reorder\_hdr | RedHat | Optional | 87 | 88 | 89 | ### _ADDR VARS_ 90 | | Variable | OS | 91 | | ---------------- | ------ | 92 | | bootproto | * | 93 | | address | * | 94 | | netmask | * | 95 | | gateway | * | 96 | | cidr | Debian | 97 | | network | Debian | 98 | | broadcast | Debian | 99 | | ipv6\_options | Debian | 100 | | ipv6\_address | * | 101 | | ipv6\_gateway | * | 102 | | name | RedHat | 103 | | nm\_controlled | RedHat | 104 | | defroute | RedHat | 105 | | stp | RedHat | 106 | | mtu | RedHat | 107 | | firewalld\_zone | RedHat | 108 | | route | Debian | 109 | | dns\_nameservers | Debian | 110 | | dns\_search | Debian | 111 | | dns\_domain | Debian | 112 | | options | Debian | 113 | | hwaddress | * | 114 | 115 | ### _BOND VARS_ 116 | | Variable | OS | 117 | | ------------------------ | ------ | 118 | | bond\_miimon | * | 119 | | bond\_lacp\_rate | Debian | 120 | | bond\_xmit\_hash\_policy | * | 121 | | bond\_downdelay | * | 122 | | bond\_updelay | * | 123 | | bond\_use\_carrier | * | 124 | | bond\_primary | * | 125 | | bond\_primary\_reselect | Debian | 126 | | bond\_bond\_ad\_select | Debian | 127 | | bond\_arp\_interval | Debian | 128 | | bond\_arp\_ip\_target | Debian | 129 | | bond\_arp\_validate | Debian | 130 | | bond\_num\_grat\_arp | Debian | 131 | | bond\_num\_unsol\_na | Debian | 132 | | bond\_active\_slave | Debian | 133 | | bond\_extra\_opts | RedHat | 134 | 135 | ### _BRIDGE VARS_ 136 | | Variable | OS | 137 | | -------------------| ------ | 138 | | bridge\_ageing | Debian | 139 | | bridge\_bridgeprio | Debian | 140 | | bridge\_fd | Debian | 141 | | bridge\_gcint | Debian | 142 | | bridge\_hello | Debian | 143 | | bridge\_maxage | Debian | 144 | | bridge\_maxwait | Debian | 145 | | bridge\_pathcost | Debian | 146 | | bridge\_portprio | Debian | 147 | | bridge\_stp | Debian | 148 | | bridge\_waitport | Debian | 149 | 150 | ## Combinations 151 | Every type of interface can be configured using `network_ether_interfaces` using the variables of the following: 152 | 153 | ethernet \ 154 | vlan \ 155 | bond \ 156 | bond slave \ 157 | bridge \ 158 | bridge port \ 159 | vlan+ethernet \ 160 | bond+ethernet \ 161 | bridge+ethernet \ 162 | bond+bridge port \ 163 | ethernet+bridge port \ 164 | vlan+bridge port 165 | 166 | 167 | 168 | Examples 169 | -------- 170 | 171 | Debian (not RedHat) network configurations can optionally use CIDR notation for IPv4 addresses instead of specifying the address and subnet mask separately. It is required to use CIDR notation for IPv6 addresses on Debian. 172 | 173 | IPv4 example with CIDR notation: 174 | ``` 175 | cidr: 192.168.10.18/24 176 | # OPTIONAL: specify a gateway for that network, or auto for network+1 177 | gateway: auto 178 | ``` 179 | 180 | IPv4 example with classic IPv4: 181 | ``` 182 | address: 192.168.10.18 183 | netmask: 255.255.255.0 184 | network: 192.168.10.0 185 | broadcast: 192.168.10.255 186 | gateway: 192.168.10.1 187 | ``` 188 | 189 | If you want to use a different MAC Address for your Interface, you can simply add it. 190 | ``` 191 | hwaddress: aa:bb:cc:dd:ee:ff 192 | ``` 193 | 194 | On some rare occasion it might be good to set whatever option you like. Therefore it 195 | is possible to use 196 | ``` 197 | options: 198 | - "up /execute/my/command" 199 | - "down /execute/my/other/command" 200 | ``` 201 | 202 | and the IPv6 version 203 | ``` 204 | ipv6_options: 205 | - "up /execute/my/command" 206 | - "down /execute/my/other/command" 207 | ``` 208 | 209 | 210 | 1) Configure eth1 and eth2 on a host with a static IP and a dhcp IP. Also 211 | define static routes and a gateway. 212 | ``` 213 | - hosts: myhost 214 | roles: 215 | - role: network 216 | network_ether_interfaces: 217 | - device: eth1 218 | bootproto: static 219 | cidr: 192.168.10.18/24 220 | gateway: auto 221 | route: 222 | - network: 192.168.200.0 223 | netmask: 255.255.255.0 224 | gateway: 192.168.10.1 225 | - network: 192.168.100.0 226 | netmask: 255.255.255.0 227 | gateway: 192.168.10.1 228 | - device: eth2 229 | bootproto: dhcp 230 | ``` 231 | 232 | Note: it is not required to add routes, default route will be added automatically. 233 | 234 | 2) Configure a bridge interface with multiple NIcs added to the bridge. 235 | ``` 236 | - hosts: myhost 237 | roles: 238 | - role: network 239 | network_bridge_interfaces: 240 | - device: br1 241 | type: bridge 242 | cidr: 192.168.10.10/24 243 | bridge_ports: [eth1, eth2] 244 | 245 | # Optional values 246 | bridge_ageing: 300 247 | bridge_bridgeprio: 32768 248 | bridge_fd: 15 249 | bridge_gcint: 4 250 | bridge_hello: 2 251 | bridge_maxage: 20 252 | bridge_maxwait: 0 253 | bridge_pathcost: "eth1 100" 254 | bridge_portprio: "eth1 128" 255 | bridge_stp: "on" 256 | bridge_waitport: "5 eth1 eth2" 257 | ``` 258 | 259 | Note: Routes can also be added for this interface in the same way routes are 260 | added for ethernet interfaces. 261 | 262 | 3) Configure a bond interface with an "active-backup" slave configuration. 263 | ``` 264 | - hosts: myhost 265 | roles: 266 | - role: network 267 | network_bond_interfaces: 268 | - device: bond0 269 | address: 192.168.10.128 270 | netmask: 255.255.255.0 271 | bond_mode: active-backup 272 | bond_slaves: [eth1, eth2] 273 | 274 | # Optional values 275 | bond_miimon: 100 276 | bond_lacp_rate: slow 277 | bond_xmit_hash_policy: layer3+4 278 | ``` 279 | 280 | 4) Configure a bonded interface with "802.3ad" as the bonding mode and IP 281 | address obtained via DHCP. 282 | ``` 283 | - hosts: myhost 284 | roles: 285 | - role: network 286 | network_bond_interfaces: 287 | - device: bond0 288 | bootproto: dhcp 289 | bond_mode: 802.3ad 290 | bond_miimon: 100 291 | bond_slaves: [eth1, eth2] 292 | bond_ad_select: 2 293 | ``` 294 | 295 | 5) Configure a VLAN interface with the vlan tag 2 for an ethernet interface 296 | ``` 297 | - hosts: myhost 298 | roles: 299 | - role: network 300 | network_ether_interfaces: 301 | - device: eth1 302 | bootproto: static 303 | cidr: 192.168.10.18/24 304 | gateway: auto 305 | network_vlan_interfaces: 306 | - device: eth1.2 307 | bootproto: static 308 | cidr: 192.168.20.18/24 309 | ``` 310 | 311 | 6) It's also possible to configure all types of interfaces manually. 312 | ``` 313 | network_ether_interfaces: 314 | - device: eth0 315 | master: bond0 316 | - device: eth1 317 | master: bond0 318 | - device: bond0 319 | type: Bond 320 | bond_mode: 802.3ad 321 | ``` 322 | 323 | 324 | 325 | Configure a bridge interface on a bond interface. The bond must be configured. 326 | ``` 327 | network_bond_interfaces: 328 | - device: bond0 329 | bridge: br0 330 | bond_mode: 802.3ad 331 | bond_miimon: 100 332 | bond_slaves: [eth0, eth1] 333 | 334 | network_bridge_interfaces: 335 | - device: br0 336 | type: Bridge 337 | address: 192.168.10.18 338 | netmask: 255.255.255.0 339 | gateway: 192.168.10.1 340 | bridge_ports: [bond0] 341 | ``` 342 | The same as the above but completely manually. 343 | ``` 344 | network_ether_interfaces: 345 | - device: eth0 346 | master: bond0 347 | - device: eth1 348 | master: bond0 349 | - device: bond0 350 | type: Bond 351 | bridge: br0 352 | bond_mode: 802.3ad 353 | bond_miimon: 100 354 | - device: br0 355 | type: Bridge 356 | address: 192.168.10.18 357 | netmask: 255.255.255.0 358 | gateway: 192.168.10.1 359 | ``` 360 | 361 | 362 | 363 | Example of creating a vlan on a bond interface. 364 | ``` 365 | network_ether_interfaces: 366 | - device: bond0.201 367 | vlan: True 368 | address: 192.168.100.78 369 | netmask: 255.255.255.0 370 | gateway: 192.168.100.1 371 | 372 | network_bond_interfaces: 373 | - device: bond0 374 | bond_mode: 802.3ad 375 | bond_miimon: 100 376 | bond_slaves: [eth0, eth1] 377 | ``` 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 7) All the above examples show how to configure a single host, The below 386 | example shows how to define your network configurations for all your machines. 387 | 388 | Assume your host inventory is as follows: 389 | 390 | ### /etc/ansible/hosts 391 | ``` 392 | [dc1] 393 | host1 394 | host2 395 | ``` 396 | 397 | Describe your network configuration for each host in host vars: 398 | 399 | ### host_vars/host1 400 | ``` 401 | network_ether_interfaces: 402 | - device: eth1 403 | bootproto: static 404 | address: 192.168.10.18 405 | netmask: 255.255.255.0 406 | gateway: 192.168.10.1 407 | route: 408 | - network: 192.168.200.0 409 | netmask: 255.255.255.0 410 | gateway: 192.168.10.1 411 | network_bond_interfaces: 412 | - device: bond0 413 | bootproto: dhcp 414 | bond_mode: 802.3ad 415 | bond_miimon: 100 416 | bond_slaves: [eth2, eth3] 417 | ``` 418 | 419 | ### host_vars/host2 420 | ``` 421 | network_ether_interfaces: 422 | - device: eth0 423 | bootproto: static 424 | address: 192.168.10.18 425 | netmask: 255.255.255.0 426 | gateway: 192.168.10.1 427 | ``` 428 | 429 | 8) If resolvconf package should be used, it is possible to add some DNS configurations 430 | ``` 431 | dns-nameserver: [ "8.8.8.8", "8.8.4.4" ] 432 | dns-search: "search.mydomain.tdl" 433 | dns-domain: "mydomain.tdl" 434 | ``` 435 | 436 | 9) You can add IPv6 static IP configuration on Ethernet, Bond or Bridge interfaces 437 | ``` 438 | ipv6_address: "aaaa:bbbb:cccc:dddd:dead:beef::1/64" 439 | ipv6_gateway: "aaaa:bbbb:cccc:dddd::1" 440 | ``` 441 | 442 | Create a playbook which applies this role to all hosts as shown below, and run 443 | the playbook. All the servers should have their network interfaces configured 444 | and routed updated. 445 | ``` 446 | - hosts: all 447 | roles: 448 | - role: network 449 | ``` 450 | 451 | 10) This role can also optionally add network interfaces to firewalld zones. The 452 | core firewalld module (http://docs.ansible.com/ansible/latest/firewalld_module.html) 453 | can perform the same function, so if you make use of both modules then your 454 | playbooks may not be idempotent. Consider this case, where only the firewalld 455 | module is used: 456 | 457 | * network_interface role runs; with no firewalld_zone host var set then any 458 | ZONE line will be removed from ifcfg-* 459 | * firewalld module runs; adds a ZONE line to ifcfg-\* 460 | * On the next playbook run, the network_interface role runs and removes the 461 | ZONE line again, and so the cycle repeats. 462 | 463 | In order for this role to manage firewalld zones, the system must be running a 464 | RHEL based distribution, and using NetworkManager to manage the network 465 | interfaces. If those criteria are met, the following example shows how to add 466 | the eth0 interface to the public firewalld zone: 467 | ``` 468 | - device: eth0 469 | bootproto: static 470 | address: 192.168.10.18 471 | netmask: 255.255.255.0 472 | gateway: 192.168.10.1 473 | firewalld_zone: public 474 | ``` 475 | 476 | Note: Ansible needs network connectivity throughout the playbook process, you 477 | may need to have a control interface that you do *not* modify using this 478 | method while changeing IP Addresses so that Ansible has a stable connection 479 | to configure the target systems. All network changes are done within a single 480 | generated script and network connectivity is only lost for few seconds. 481 | 482 | 483 | Dependencies 484 | ------------ 485 | 486 | python-netaddr 487 | 488 | License 489 | ------- 490 | 491 | BSD 492 | 493 | Author Information 494 | ------------------ 495 | 496 | This project was originally created by [Benno Joy](https://github.com/bennojoy/network_interface). 497 | 498 | Debian upgrades by: 499 | 500 | * Martin Verges (croit, GmbH) 501 | 502 | RedHat upgrades by: 503 | 504 | * Eric Anderson (Avi Networks, Inc.) 505 | * Luke Short (Red Hat, Inc.) 506 | * Wei Tie, (Cisco Systems, Inc.) 507 | 508 | The full list of contributors can be found [here](https://github.com/MartinVerges/ansible.network_interface/graphs/contributors). 509 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | network_pkgs: [] 3 | network_ether_interfaces: [] 4 | network_bridge_interfaces: [] 5 | network_bond_interfaces: [] 6 | network_vlan_interfaces: [] 7 | network_check_packages: true 8 | network_allow_service_restart: true 9 | network_modprobe_persist: true 10 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | role_name: network_interface 4 | author: "Benno Joy, Martin Verges, Luke Short, Eric Anderson" 5 | company: "AnsibleWorks, First Colo GmbH" 6 | license: "Simplified BSD License" 7 | min_ansible_version: 1.9 8 | platforms: 9 | - name: Debian 10 | versions: 11 | - wheezy 12 | - jessie 13 | - name: Ubuntu 14 | versions: 15 | - precise 16 | - quantal 17 | - raring 18 | - saucy 19 | - trusty 20 | - utopic 21 | - vivid 22 | - name: EL 23 | galaxy_tags: 24 | - networking 25 | - system 26 | dependencies: [] 27 | -------------------------------------------------------------------------------- /tasks/debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install the required packages in Debian derivatives 3 | apt: 4 | name: "{{ network_pkgs }}" 5 | state: present 6 | environment: "{{ env }}" 7 | when: network_check_packages 8 | 9 | - name: Make sure the include line is there in interfaces file 10 | lineinfile: 11 | regexp: '^source\ {{ net_path | regex_escape() }}/\*' 12 | line: "source {{ net_path }}/*" 13 | dest: /etc/network/interfaces 14 | state: present 15 | insertafter: EOF 16 | 17 | - name: Create the directory for interface cfg files 18 | file: 19 | path: "{{ net_path }}" 20 | state: directory 21 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add the OS specific varibles 3 | include_vars: "{{ ansible_os_family }}.yml" 4 | 5 | - name: Include specific tasks for the RedHat family 6 | include: redhat.yml 7 | when: ansible_os_family == 'RedHat' 8 | 9 | - name: Include specific tasks for the Debian family 10 | include: debian.yml 11 | when: ansible_os_family == "Debian" 12 | 13 | 14 | # Create network configuration files for any general interface 15 | - name: Create the network configuration file for ethernet interfaces 16 | template: 17 | src: "ethernet_{{ ansible_os_family }}.j2" 18 | dest: "{{ net_path }}/ifcfg-{{ item.device }}" 19 | with_items: "{{ network_ether_interfaces }}" 20 | when: network_ether_interfaces is defined 21 | register: ether_result 22 | 23 | 24 | # Create configs for bond devices and their slaves 25 | - name: Create the network configuration file for slave in the bond devices 26 | template: 27 | src: "bond_slave_{{ ansible_os_family }}.j2" 28 | dest: "{{ net_path }}/ifcfg-{{ item.1 }}" 29 | with_subelements: 30 | - "{{ network_bond_interfaces }}" 31 | - bond_slaves 32 | when: network_bond_interfaces is defined and 33 | not item.1 in network_ether_interfaces|map(attribute='device')|list and 34 | not item.1 in network_bridge_interfaces|map(attribute='device')|list and 35 | not item.1 in network_vlan_interfaces|map(attribute='device')|list 36 | register: bond_port_result 37 | 38 | - name: Create the network configuration file for bond devices 39 | template: 40 | src: "bond_{{ ansible_os_family }}.j2" 41 | dest: "{{ net_path }}/ifcfg-{{ item.device }}" 42 | with_items: "{{ network_bond_interfaces }}" 43 | when: network_bond_interfaces 44 | register: bond_result 45 | 46 | - name: Make sure the bonding module is loaded 47 | modprobe: 48 | name: bonding 49 | state: present 50 | when: bond_result is changed 51 | 52 | - name: Make the bonding module persistent 53 | become: true 54 | lineinfile: 55 | line: 'bonding' 56 | dest: /etc/modules 57 | insertafter: EOF 58 | when: 59 | - network_bond_interfaces 60 | - network_modprobe_persist 61 | 62 | 63 | # Create configs for vlans 64 | - name: Create the network configuration file for vlan devices 65 | template: 66 | src: "ethernet_{{ ansible_os_family }}.j2" 67 | dest: "{{ net_path }}/ifcfg-{{ item.device }}" 68 | with_items: "{{ network_vlan_interfaces }}" 69 | when: network_vlan_interfaces 70 | register: vlan_result 71 | 72 | - name: Make sure the 8021q module is loaded 73 | modprobe: 74 | name: 8021q 75 | state: present 76 | when: vlan_result is changed 77 | 78 | - name: Make the 8021q module persistent 79 | become: true 80 | lineinfile: 81 | line: '8021q' 82 | dest: /etc/modules 83 | insertafter: EOF 84 | when: 85 | - network_vlan_interfaces 86 | - network_modprobe_persist 87 | 88 | 89 | # Create configs for bridge devices and their ports 90 | - name: Create the network configuration file for bridge devices 91 | template: 92 | src: "bridge_{{ ansible_os_family }}.j2" 93 | dest: "{{ net_path }}/ifcfg-{{ item.device }}" 94 | with_items: "{{ network_bridge_interfaces }}" 95 | when: network_bridge_interfaces is defined 96 | register: bridge_result 97 | 98 | - name: Create the network configuration file for port on the bridge devices 99 | template: 100 | src: "bridge_port_{{ ansible_os_family }}.j2" 101 | dest: "{{ net_path }}/ifcfg-{{ item.1 }}" 102 | with_subelements: 103 | - '{{ network_bridge_interfaces }}' 104 | - bridge_ports 105 | - skip_missing: True 106 | when: network_bridge_interfaces is defined and 107 | not item.1 in network_ether_interfaces|map(attribute='device')|list and 108 | not item.1 in network_bond_interfaces|map(attribute='device')|list and 109 | not item.1 in network_vlan_interfaces|map(attribute='device')|list 110 | register: bridge_port_result 111 | 112 | 113 | # Restart Network Interfaces (deconfigurate & reconfigurate interfaces) 114 | - include: restartscript.yml 115 | when: network_allow_service_restart and ansible_os_family == 'Debian' 116 | and (ether_result is changed 117 | or bond_port_result is changed 118 | or bond_result is changed 119 | or vlan_result is changed 120 | or bridge_result is changed 121 | or bridge_port_result is changed) 122 | 123 | - name: Enable the "network" service 124 | service: 125 | name: network 126 | enabled: true 127 | check_mode: yes 128 | register: network_service 129 | ignore_errors: true 130 | when: network_allow_service_restart and ansible_os_family == 'RedHat' 131 | 132 | - name: Verify if the "network" service is enabled 133 | set_fact: 134 | network_service_enabled: "{{ not network_service.failed 135 | and not network_service.changed }}" 136 | when: network_allow_service_restart and ansible_os_family == 'RedHat' 137 | 138 | - name: Enable the "NetworkManager" service 139 | service: 140 | name: NetworkManager 141 | enabled: true 142 | check_mode: yes 143 | register: NetworkManager_service 144 | ignore_errors: true 145 | when: network_allow_service_restart and ansible_os_family == 'RedHat' 146 | 147 | - name: Verify if the "NetworkManager" service is enabled 148 | set_fact: 149 | NetworkManager_service_enabled: "{{ not NetworkManager_service.failed 150 | and not NetworkManager_service.changed }}" 151 | when: network_allow_service_restart and ansible_os_family == 'RedHat' 152 | 153 | - name: Restart the "network" service on Red Hat systems 154 | service: 155 | name: network 156 | state: restarted 157 | when: > 158 | (network_allow_service_restart 159 | and ansible_os_family == 'RedHat' 160 | and network_service_enabled) 161 | and (ether_result is changed 162 | or bond_port_result is changed 163 | or bond_result is changed 164 | or vlan_result is changed 165 | or bridge_result is changed 166 | or bridge_port_result is changed) 167 | 168 | - name: Restart the "NetworkManager" service on Red Hat systems 169 | service: 170 | name: NetworkManager 171 | state: restarted 172 | when: > 173 | (network_allow_service_restart 174 | and ansible_os_family == 'RedHat' 175 | and NetworkManager_service_enabled) and 176 | (ether_result is changed or 177 | bond_port_result is changed or 178 | bond_result is changed or 179 | vlan_result is changed or 180 | bridge_result is changed or 181 | bridge_port_result is changed) 182 | -------------------------------------------------------------------------------- /tasks/redhat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install the required packages in Redhat derivatives 3 | yum: 4 | name: "{{ network_pkgs }}" 5 | state: present 6 | when: network_check_packages 7 | 8 | - name: Write configuration files for rhel route configuration with vlan 9 | template: 10 | src: "route_{{ ansible_os_family }}.j2" 11 | dest: "{{ net_path }}/route-{{ item.device }}" 12 | with_items: "{{ network_vlan_interfaces }}" 13 | when: network_ether_interfaces is defined and item.route is defined 14 | 15 | - name: Write configuration files for rhel route configuration 16 | template: 17 | src: "route_{{ ansible_os_family }}.j2" 18 | dest: "{{ net_path }}/route-{{ item.device }}" 19 | with_items: "{{ network_ether_interfaces }}" 20 | when: network_ether_interfaces is defined and item.route is defined 21 | 22 | - name: Write configuration files for route configuration 23 | template: 24 | src: "route_{{ ansible_os_family }}.j2" 25 | dest: "{{ net_path }}/route-{{ item.device }}" 26 | with_items: "{{ network_bond_interfaces }}" 27 | when: network_bond_interfaces is defined and item.route is defined 28 | 29 | - name: Write configuration files for rhel route configuration 30 | template: 31 | src: "route_{{ ansible_os_family }}.j2" 32 | dest: "{{ net_path }}/route-{{ item.device }}" 33 | with_items: "{{ network_bridge_interfaces }}" 34 | when: network_bridge_interfaces is defined and item.route is defined 35 | 36 | - name: Cleanup gateway dev that is not set to the one we want 37 | lineinfile: 38 | dest: /etc/sysconfig/network 39 | regexp: "^GATEWAYDEV=(?!{{ gateway_dev }})" 40 | state: absent 41 | when: gateway_dev is defined 42 | 43 | - name: Explicitly set the gateway device 44 | lineinfile: 45 | dest: /etc/sysconfig/network 46 | line: "GATEWAYDEV={{ gateway_dev }}" 47 | when: gateway_dev is defined 48 | -------------------------------------------------------------------------------- /tasks/restartscript.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Restart interfaces to load new configuration 3 | # 4 | # We had a lot of problems with lost connectivity, therefore we changed the 5 | # role to use a script for network reconfiguration. 6 | # Tested on Debian Jessie / Ubuntu 14.04 LTS and with Ethernet, Bonding Interfaces 7 | 8 | - name: Create a restart script 9 | template: 10 | src: restartscript.j2 11 | dest: /etc/network/restart.sh 12 | mode: 0755 13 | 14 | # Execute configuration change 15 | - name: Execute Network Restart 16 | shell: bash /etc/network/restart.sh | true 17 | 18 | - name: Cleanup Network Restart script 19 | file: 20 | path: /etc/network/restart.sh 21 | state: absent 22 | -------------------------------------------------------------------------------- /templates/Debian_bond_options.j2: -------------------------------------------------------------------------------- 1 | bond-mode {{ item.bond_mode }} 2 | bond-miimon {{ item.bond_miimon | default(100) }} 3 | {% if item.bond_mode == '802.3ad' or item.bond_mode == 4 %} 4 | bond-lacp-rate {{ item.bond_lacp_rate | default('slow') }} 5 | {% endif %} 6 | {% if item.bond_mode == 2 or item.bond_mode == 'balance-xor' 7 | or item.bond_mode == 4 or item.bond_mode == '802.3ad' 8 | or item.bond_mode == 6 or item.bond_mode == 'balance-tlb' 9 | %} 10 | bond-xmit-hash-policy {{ item.bond_xmit_hash_policy | default('layer3+4') }} 11 | {% endif %} 12 | {% if item.bond_downdelay is defined %} 13 | bond-downdelay {{ item.bond_downdelay }} 14 | {% endif %} 15 | {% if item.bond_updelay is defined %} 16 | bond-updelay {{ item.bond_updelay }} 17 | {% endif %} 18 | {% if item.bond_ad_select is defined %} 19 | bond-ad-select {{ item.bond_ad_select }} 20 | {% endif %} 21 | {% if item.bond_arp_interval is defined %} 22 | bond-arp-interval {{ item.bond_arp_interval }} 23 | {% endif %} 24 | {% if item.bond_arp_ip_target is defined %} 25 | bond-arp-ip-target {{ item.bond_arp_ip_target }} 26 | {% endif %} 27 | {% if item.bond_arp_validate is defined %} 28 | bond-arp-validate {{ item.bond_arp_validate }} 29 | {% endif %} 30 | {% if item.bond_num_grat_arp is defined %} 31 | bond-num-grat-arp {{ item.bond_num_grat_arp }} 32 | {% endif %} 33 | {% if item.bond_num_unsol_na is defined %} 34 | bond-num-unsol-na {{ item.bond_num_unsol_na }} 35 | {% endif %} 36 | {% if item.bond_primary is defined %} 37 | bond-primary {{ item.bond_primary }} 38 | {% endif %} 39 | {% if item.bond_primary_reselect is defined %} 40 | bond-primary-reselect {{ item.bond_primary_reselect }} 41 | {% endif %} 42 | {% if item.bond_use_carrier is defined %} 43 | bond-use-carrier {{ item.bond_use_carrier }} 44 | {% endif %} 45 | {% if item.bond_slaves is defined %} 46 | bond-slaves {{ item.bond_slaves|join(' ') }} 47 | {% endif %} 48 | {% if item.bond_active_slave is defined %} 49 | bond-active-slave {{ item.bond_active_slave }} 50 | {% endif %} 51 | -------------------------------------------------------------------------------- /templates/Debian_bridge_options.j2: -------------------------------------------------------------------------------- 1 | {% if item.bridge_ports is defined %} 2 | bridge_ports {{ item.bridge_ports|join(' ') }} 3 | {% else %} 4 | bridge_ports none 5 | {% endif %} 6 | {% if item.bridge_ageing is defined %} 7 | bridge_ageing {{ item.bridge_ageing }} 8 | {% endif %} 9 | {% if item.bridge_bridgeprio is defined %} 10 | bridge_bridgeprio {{ item.bridge_bridgeprio }} 11 | {% endif %} 12 | {% if item.bridge_fd is defined %} 13 | bridge_fd {{ item.bridge_fd }} 14 | {% endif %} 15 | {% if item.bridge_gcint is defined %} 16 | bridge_gcint {{ item.bridge_gcint }} 17 | {% endif %} 18 | {% if item.bridge_hello is defined %} 19 | bridge_hello {{ item.bridge_hello }} 20 | {% endif %} 21 | {% if item.hwaddress is defined %} 22 | bridge_hw {{ item.hwaddress }} 23 | {% endif %} 24 | {% if item.bridge_maxage is defined %} 25 | bridge_maxage {{ item.bridge_maxage }} 26 | {% endif %} 27 | {% if item.bridge_maxwait is defined %} 28 | bridge_maxwait {{ item.bridge_maxwait }} 29 | {% endif %} 30 | {% if item.bridge_pathcost is defined %} 31 | bridge_pathcost {{ item.bridge_pathcost }} 32 | {% endif %} 33 | {% if item.bridge_portprio is defined %} 34 | bridge_portprio {{ item.bridge_portprio }} 35 | {% endif %} 36 | {% if item.bridge_stp is defined %} 37 | bridge_stp {{ item.bridge_stp }} 38 | {% endif %} 39 | {% if item.bridge_waitport is defined %} 40 | bridge_waitport {{ item.bridge_waitport }} 41 | {% endif %} 42 | -------------------------------------------------------------------------------- /templates/Debian_ipv4_config.j2: -------------------------------------------------------------------------------- 1 | {% if item.cidr is defined %} 2 | address {{ item.cidr | ipaddr('address') }} 3 | network {{ item.cidr | ipaddr('network') }} 4 | netmask {{ item.cidr | ipaddr('netmask') }} 5 | broadcast {{ item.cidr | ipaddr('broadcast') }} 6 | {% elif item.address is defined and item.netmask is defined %} 7 | {% if item.address is defined %} 8 | address {{ item.address }} 9 | {% endif %} 10 | {% if item.netmask is defined %} 11 | netmask {{ item.netmask }} 12 | {% endif %} 13 | {% if item.network is defined %} 14 | network {{ item.network }} 15 | {% endif %} 16 | {% if item.broadcast is defined %} 17 | broadcast {{ item.broadcast }} 18 | {% endif %} 19 | {% endif %} 20 | {% if item.gateway is defined and item.gateway != 'auto' %} 21 | gateway {{ item.gateway }} 22 | {% elif item.cidr is defined and item.gateway is defined and item.gateway == 'auto' %} 23 | gateway {{ item.cidr | ipaddr('1') | ipaddr('address') }} 24 | {% endif %} 25 | 26 | -------------------------------------------------------------------------------- /templates/Debian_ipv6_config.j2: -------------------------------------------------------------------------------- 1 | {% if item.ipv6_address is defined %} 2 | address {{ item.ipv6_address | ipaddr('address') }} 3 | netmask {{ item.ipv6_address | ipaddr('prefix') }} 4 | {% if item.ipv6_gateway is defined and item.ipv6_gateway != 'auto' %} 5 | gateway {{ item.ipv6_gateway }} 6 | {% elif item.ipv6_gateway is defined and item.ipv6_gateway == 'auto' %} 7 | gateway {{ item.ipv6_address | ipaddr('1') | ipaddr('address') }} 8 | {% endif %} 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /templates/Debian_resolvconf.j2: -------------------------------------------------------------------------------- 1 | {% if item.dns_nameservers is defined %} 2 | dns-nameservers {{ item.dns_nameservers|join(' ') }} 3 | {% endif %} 4 | {% if item.dns_search is defined %} 5 | dns-search {{ item.dns_search }} 6 | {% endif %} 7 | {% if item.dns_domain is defined %} 8 | dns-domain {{ item.dns_domain }} 9 | {% endif %} 10 | 11 | -------------------------------------------------------------------------------- /templates/RedHat_bond_options.j2: -------------------------------------------------------------------------------- 1 | BONDING_OPTS="mode={{ item.bond_mode }} miimon={{ item.bond_miimon|default(100) }} 2 | {%- if item.bond_xmit_hash_policy is defined %} 3 | xmit_hash_policy={{ item.bond_xmit_hash_policy }} 4 | {%- endif -%} 5 | {%- if item.bond_downdelay is defined %} 6 | downdelay={{ item.bond_downdelay }} 7 | {%- endif -%} 8 | {%- if item.bond_updelay is defined %} 9 | updelay={{ item.bond_updelay }} 10 | {%- endif -%} 11 | {%- if item.bond_primary is defined %} 12 | primary={{ item.bond_primary }} 13 | {%- endif -%} 14 | {%- if item.bond_use_carrier is defined %} 15 | use_carrier={{ item.bond_use_carrier }} 16 | {%- endif -%} 17 | {%- if item.bond_ad_select is defined %} 18 | ad_select={{ item.bond_ad_select }} 19 | {%- endif -%} 20 | {%- if item.bond_extra_opts is defined %} 21 | {{ item.bond_extra_opts }} 22 | {%- endif -%} 23 | " 24 | -------------------------------------------------------------------------------- /templates/RedHat_generic_options.j2: -------------------------------------------------------------------------------- 1 | {% if item.dns_nameservers is defined %} 2 | {% for dns_nameserver in item.dns_nameservers %} 3 | DNS{{ loop.index }}={{ dns_nameserver }} 4 | {% endfor %} 5 | {% endif -%} 6 | 7 | {% if item.nm_controlled is defined %} 8 | NM_CONTROLLED={{ item.nm_controlled | bool | ternary("yes", "no") }} 9 | {% endif -%} 10 | 11 | {% if item.defroute is defined %} 12 | DEFROUTE={{ item.defroute | bool | ternary("yes", "no") }} 13 | {% endif -%} 14 | 15 | {% if item.stp is defined %} 16 | STP={{ item.stp }} 17 | {% endif -%} 18 | 19 | {% if item.mtu is defined %} 20 | MTU={{ item.mtu }} 21 | {% endif -%} 22 | 23 | {% if item.firewalld_zone is defined %} 24 | ZONE={{ item.firewalld_zone }} 25 | {% endif -%} 26 | 27 | ONBOOT={{ item.onboot|default("yes") }} 28 | -------------------------------------------------------------------------------- /templates/RedHat_ipv6_options.j2: -------------------------------------------------------------------------------- 1 | {% if item.ipv6_address is defined %} 2 | IPV6INIT="yes" 3 | IPV6_AUTOCONF="yes" 4 | IPV6_DEFROUTE="yes" 5 | IPV6_FAILURE_FATAL="no" 6 | IPV6_FORWARDING="yes" 7 | IPV6_PEERDNS="yes" 8 | IPV6_PEERROUTES="yes" 9 | IPV6_PRIVACY="no" 10 | IPV6ADDR={{ item.ipv6_address }} 11 | {% endif -%} 12 | 13 | {% if item.ipv6_gateway is defined %} 14 | IPV6_DEFAULTGW="{{ item.ipv6_gateway }}" 15 | {% endif -%} 16 | -------------------------------------------------------------------------------- /templates/RedHat_vlan_options.j2: -------------------------------------------------------------------------------- 1 | VLAN=yes 2 | {% if item.vlan_physdev is defined %} 3 | PHYSDEV={{ item.vlan_physdev }} 4 | {% else %} 5 | PHYSDEV={{ item.device.rpartition('.')[0] }} 6 | {% endif -%} 7 | 8 | {% if item.vlan_id is defined %} 9 | VLAN_ID={{ item.vlan_id }} 10 | {% else %} 11 | VLAN_ID={{ item.device.rpartition('.')[2] }} 12 | {% endif -%} 13 | 14 | {% if item.reorder_hdr is defined %} 15 | REORDER_HDR={{ item.reorder_hdr }} 16 | {% endif %} 17 | -------------------------------------------------------------------------------- /templates/bond_Debian.j2: -------------------------------------------------------------------------------- 1 | 2 | auto {{ item.device }} 3 | iface {{ item.device }} inet {% if item.bootproto is defined %}{{ item.bootproto }}{% elif item.cidr is defined or item.address is defined %}static{% else %}dhcp{% endif %} 4 | 5 | {% include 'Debian_ipv4_config.j2' %} 6 | {% include 'Debian_resolvconf.j2' %} 7 | {% include 'route_Debian.j2' %} 8 | 9 | {% if item.bond_mode is defined and item.bond_slaves is defined %} 10 | {% include 'Debian_bond_options.j2' %} 11 | {% endif %} 12 | 13 | {% if item.hwaddress is defined %} 14 | hwaddress ether {{ item.hwaddress }} 15 | {% endif %} 16 | 17 | {% if item.options is defined %} 18 | {% for option in item.options %} 19 | {{ option }} 20 | {% endfor %} 21 | {% endif %} 22 | 23 | {% if item.ipv6_address is defined %} 24 | iface {{ item.device }} inet6 static 25 | {% include 'Debian_ipv6_config.j2' %} 26 | {% if item.ipv6_options is defined %} 27 | {% for option in item.ipv6_options %} 28 | {{ option }} 29 | {% endfor %} 30 | {% endif %} 31 | {% endif %} 32 | -------------------------------------------------------------------------------- /templates/bond_RedHat.j2: -------------------------------------------------------------------------------- 1 | #jinja2: lstrip_blocks: "True", trim_blocks: "True" 2 | NAME={{ item.name | default(item.device) }} 3 | DEVICE={{ item.device }} 4 | TYPE=Bond 5 | USERCTL=no 6 | {% if item.bootproto is defined and item.bootproto == 'dhcp' %} 7 | BOOTPROTO=dhcp 8 | {% else %} 9 | BOOTPROTO={{ item.bootproto|default('none') }} 10 | {% if item.address is defined %} 11 | IPADDR={{ item.address }} 12 | {% endif -%} 13 | 14 | {% if item.netmask is defined %} 15 | NETMASK={{ item.netmask }} 16 | {% endif -%} 17 | 18 | {% if item.gateway is defined %} 19 | GATEWAY={{ item.gateway }} 20 | {% endif -%} 21 | {% endif -%} 22 | 23 | BONDING_MASTER=yes 24 | {% include "RedHat_bond_options.j2" %} 25 | 26 | {% if item.bridge is defined %} 27 | BRIDGE={{ item.bridge }} 28 | {% endif -%} 29 | 30 | {% include "RedHat_ipv6_options.j2" -%} 31 | 32 | {% include "RedHat_generic_options.j2" %} 33 | -------------------------------------------------------------------------------- /templates/bond_slave_Debian.j2: -------------------------------------------------------------------------------- 1 | auto {{ item.1 }} 2 | iface {{ item.1 }} inet manual 3 | bond-master {{ item.0.device }} 4 | {% if item.0.bond_primary is defined and item.1 == item.0.bond_primary %} 5 | bond-primary {{ item.0.bond_primary }} 6 | {% endif %} 7 | -------------------------------------------------------------------------------- /templates/bond_slave_RedHat.j2: -------------------------------------------------------------------------------- 1 | NAME={{ item.1 }} 2 | DEVICE={{ item.1 }} 3 | BOOTPROTO=none 4 | MASTER={{ item.0.device }} 5 | ONBOOT=yes 6 | SLAVE=yes 7 | USERCTL=no 8 | -------------------------------------------------------------------------------- /templates/bridge_Debian.j2: -------------------------------------------------------------------------------- 1 | 2 | auto {{ item.device }} 3 | iface {{ item.device }} inet {% if item.bootproto is defined %}{{ item.bootproto }}{% elif item.cidr is defined or item.address is defined %}static{% else %}dhcp{% endif %} 4 | 5 | {% include 'Debian_ipv4_config.j2' %} 6 | {% include 'Debian_resolvconf.j2' %} 7 | {% include 'route_Debian.j2' %} 8 | {% include 'Debian_bridge_options.j2' %} 9 | 10 | {% if item.ipv6_address is defined %} 11 | iface {{ item.device }} inet6 static 12 | {% include 'Debian_ipv6_config.j2' %} 13 | {% if item.ipv6_options is defined %} 14 | {% for option in item.ipv6_options %} 15 | {{ option }} 16 | {% endfor %} 17 | {% endif %} 18 | {% endif %} 19 | 20 | -------------------------------------------------------------------------------- /templates/bridge_RedHat.j2: -------------------------------------------------------------------------------- 1 | #jinja2: lstrip_blocks: "True", trim_blocks: "True" 2 | NAME={{ item.name | default(item.device) }} 3 | DEVICE={{ item.device }} 4 | TYPE=Bridge 5 | {% if item.bootproto is defined and item.bootproto == 'dhcp' %} 6 | BOOTPROTO=dhcp 7 | {% else %} 8 | BOOTPROTO={{ item.bootproto|default("none") }} 9 | {% if item.address is defined %} 10 | IPADDR={{ item.address }} 11 | {% endif -%} 12 | 13 | {% if item.netmask is defined %} 14 | NETMASK={{ item.netmask }} 15 | {% endif -%} 16 | 17 | {% if item.gateway is defined %} 18 | GATEWAY={{ item.gateway }} 19 | {% endif -%} 20 | {% endif -%} 21 | 22 | {% include "RedHat_ipv6_options.j2" -%} 23 | 24 | {% include "RedHat_generic_options.j2" %} 25 | -------------------------------------------------------------------------------- /templates/bridge_port_Debian.j2: -------------------------------------------------------------------------------- 1 | auto {{ item.1 }} 2 | iface {{ item.1 }} inet manual 3 | {% if item.0.promisc is defined %} 4 | up /sbin/ifconfig {{ item.1 }} promisc {{ item.0.promisc }} 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /templates/bridge_port_RedHat.j2: -------------------------------------------------------------------------------- 1 | NAME={{ item.1 }} 2 | DEVICE={{ item.1 }} 3 | TYPE=Ethernet 4 | BOOTPROTO=none 5 | ONBOOT={{ item.onboot|default("yes") }} 6 | BRIDGE={{ item.0.device }} 7 | {% if item.mtu is defined %} 8 | MTU={{ item.mtu }} 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /templates/ethernet_Debian.j2: -------------------------------------------------------------------------------- 1 | 2 | auto {{ item.device }} 3 | iface {{ item.device }} inet {% if item.bootproto is defined %}{{ item.bootproto }}{% elif item.cidr is defined or item.address is defined %}static{% else %}dhcp{% endif %} 4 | 5 | {% include 'Debian_ipv4_config.j2' %} 6 | {% include 'Debian_resolvconf.j2' %} 7 | {% include 'route_Debian.j2' %} 8 | {% if item.hwaddress is defined %} 9 | hwaddress ether {{ item.hwaddress }} 10 | {% endif %} 11 | {% if item.options is defined %} 12 | {% for option in item.options %} 13 | {{ option }} 14 | {% endfor %} 15 | {% endif %} 16 | 17 | {% if item.ipv6_address is defined %} 18 | iface {{ item.device }} inet6 static 19 | {% include 'Debian_ipv6_config.j2' %} 20 | {% if item.ipv6_options is defined %} 21 | {% for option in item.ipv6_options %} 22 | {{ option }} 23 | {% endfor %} 24 | {% endif %} 25 | {% endif %} 26 | 27 | -------------------------------------------------------------------------------- /templates/ethernet_RedHat.j2: -------------------------------------------------------------------------------- 1 | #jinja2: lstrip_blocks: "True", trim_blocks: "True" 2 | NAME={{ item.name | default(item.device) }} 3 | DEVICE={{ item.device }} 4 | TYPE={{ item.type | default("Ethernet") }} 5 | {% if item.bootproto is defined and item.bootproto == 'dhcp' %} 6 | BOOTPROTO=dhcp 7 | {% else %} 8 | BOOTPROTO={{ item.bootproto|default("none") }} 9 | {% if item.address is defined %} 10 | IPADDR={{ item.address }} 11 | {% endif -%} 12 | 13 | {% if item.netmask is defined %} 14 | NETMASK={{ item.netmask }} 15 | {% endif -%} 16 | 17 | {% if item.gateway is defined %} 18 | GATEWAY={{ item.gateway }} 19 | {% endif -%} 20 | {% endif -%} 21 | 22 | {% if item.hwaddress is defined %} 23 | HWADDR={{ item.hwaddress }} 24 | {% endif -%} 25 | 26 | {% if item.vlan is defined and item.vlan | bool %} 27 | {% include "RedHat_vlan_options.j2" %} 28 | {% endif -%} 29 | 30 | {% if item.bridge is defined %} 31 | BRIDGE={{ item.bridge }} 32 | {% endif -%} 33 | 34 | {% if item.type is defined and item.type == "Bond" %} 35 | BONDING_MASTER=yes 36 | {% include "RedHat_bond_options.j2" %} 37 | 38 | {% endif -%} 39 | 40 | {% if item.master is defined %} 41 | MASTER={{ item.master }} 42 | SLAVE=yes 43 | {% endif -%} 44 | 45 | {% include "RedHat_ipv6_options.j2" -%} 46 | 47 | {% include "RedHat_generic_options.j2" %} 48 | -------------------------------------------------------------------------------- /templates/restartscript.j2: -------------------------------------------------------------------------------- 1 | # Shutdown current network configuration 2 | # Ethernet 3 | {% if ether_result is defined and 'results' in ether_result %}{% for item in ether_result.results %} 4 | ifdown {{ item.item.device }} 5 | {% endfor %}{% endif %} 6 | # Bonding 7 | {% if bond_port_result is defined and 'results' in bond_port_result %}{% for item in bond_port_result.results %} 8 | ifdown {{ item.item.1 }} 9 | {% endfor %}{% endif %} 10 | {% if bond_result is defined and 'results' in bond_result %}{% for item in bond_result.results %} 11 | ifdown {{ item.item.device }} 12 | {% endfor %}{% endif %} 13 | # Vlan 14 | {% if vlan_result is defined %}{% for item in vlan_result.results %} 15 | ifdown {{ item.item.device }} 16 | {% endfor %}{% endif %} 17 | # Bridge 18 | {% if bridge_port_result is defined and 'results' in bridge_port_result %}{% for item in bridge_port_result.results %} 19 | ifdown {{ item.item.1 }} 20 | {% endfor %}{% endif %} 21 | {% if bridge_result is defined and 'results' in bridge_result %}{% for item in bridge_result.results %} 22 | ifdown {{ item.item.device }} 23 | {% endfor %}{% endif %} 24 | 25 | # Short delay to prevent issues 26 | sleep 1 27 | 28 | # Start new network configuration 29 | # Ethernet 30 | {% if ether_result is defined and 'results' in ether_result %}{% for item in ether_result.results %} 31 | ifup {{ item.item.device }} 32 | {% endfor %}{% endif %} 33 | # Bonding 34 | {% if bond_port_result is defined and 'results' in bond_port_result %}{% for item in bond_port_result.results %} 35 | ifup {{ item.item.1 }} 36 | {% endfor %}{% endif %} 37 | {% if bond_result is defined and 'results' in bond_result %}{% for item in bond_result.results %} 38 | ifup {{ item.item.device }} 39 | {% endfor %}{% endif %} 40 | # Vlan 41 | {% if vlan_result is defined %}{% for item in vlan_result.results %} 42 | ifup {{ item.item.device }} 43 | {% endfor %}{% endif %} 44 | # Bridge 45 | {% if bridge_port_result is defined and 'results' in bridge_port_result %}{% for item in bridge_port_result.results %} 46 | ifup {{ item.item.1 }} 47 | {% endfor %}{% endif %} 48 | {% if bridge_result is defined and 'results' in bridge_result %}{% for item in bridge_result.results %} 49 | ifup {{ item.item.device }} 50 | {% endfor %}{% endif %} 51 | 52 | 53 | -------------------------------------------------------------------------------- /templates/route_Debian.j2: -------------------------------------------------------------------------------- 1 | {% if item.route is defined %} 2 | {% for i in item.route %} 3 | {% if i.cidr is defined %} 4 | up ip route add {{ i.cidr }} via {{ i.gateway }} dev {{ item.device }} 5 | {% else %} 6 | up route add -net {{ i.network }} netmask {{ i.netmask }} gw {{ i.gateway }} {{ item.device }} 7 | {% endif %} 8 | {% endfor %} 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /templates/route_RedHat.j2: -------------------------------------------------------------------------------- 1 | #jinja2: lstrip_blocks: "True", trim_blocks: "True" 2 | {% for i in item.route %} 3 | {% if i is mapping %} 4 | ADDRESS{{ loop.index - 1 }}={{ i.network }} 5 | NETMASK{{ loop.index - 1 }}={{ i.netmask }} 6 | {% if i.gateway is defined %} 7 | GATEWAY{{ loop.index - 1 }}={{ i.gateway }} 8 | {% endif %} 9 | {% else %} 10 | {{ i }} 11 | {% endif %} 12 | {% endfor %} 13 | -------------------------------------------------------------------------------- /tests/Dockerfile.centos-7: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | # Install systemd -- See https://hub.docker.com/_/centos/ 4 | RUN yum -y swap -- remove fakesystemd -- install systemd systemd-libs 5 | RUN yum -y update; yum clean all; \ 6 | (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ 7 | rm -f /lib/systemd/system/multi-user.target.wants/*; \ 8 | rm -f /etc/systemd/system/*.wants/*; \ 9 | rm -f /lib/systemd/system/local-fs.target.wants/*; \ 10 | rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ 11 | rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ 12 | rm -f /lib/systemd/system/basic.target.wants/*; \ 13 | rm -f /lib/systemd/system/anaconda.target.wants/*; 14 | 15 | # Install Ansible 16 | RUN yum -y install epel-release 17 | RUN yum -y install git ansible sudo 18 | RUN yum clean all 19 | 20 | # Disable requiretty 21 | RUN sed -i -e 's/^\(Defaults\s*requiretty\)/#--- \1/' /etc/sudoers 22 | 23 | # Install Ansible inventory file 24 | RUN echo -e '[local]\nlocalhost ansible_connection=local' > /etc/ansible/hosts 25 | 26 | VOLUME ["/sys/fs/cgroup"] 27 | CMD ["/usr/sbin/init"] 28 | -------------------------------------------------------------------------------- /tests/Dockerfile.ubuntu-14.04: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | RUN apt-get update 3 | 4 | # Install Ansible 5 | RUN apt-get install -y software-properties-common git 6 | RUN apt-add-repository -y ppa:ansible/ansible 7 | RUN apt-get update 8 | RUN apt-get install -y ansible 9 | 10 | # Install Ansible inventory file 11 | RUN echo "[local]\nlocalhost ansible_connection=local" > /etc/ansible/hosts 12 | -------------------------------------------------------------------------------- /tests/Dockerfile.ubuntu-16.04: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | RUN apt-get update 3 | 4 | # Install Ansible 5 | RUN apt-get install -y software-properties-common git 6 | RUN apt-add-repository -y ppa:ansible/ansible 7 | RUN apt-get update 8 | RUN apt-get install -y ansible 9 | 10 | # Install Ansible inventory file 11 | RUN echo "[local]\nlocalhost ansible_connection=local" > /etc/ansible/hosts 12 | -------------------------------------------------------------------------------- /tests/test.yml: -------------------------------------------------------------------------------- 1 | - hosts: all 2 | 3 | pre_tasks: 4 | - name: Ensure build dependencies are installed (RedHat). 5 | yum: 'name="{{ item }}" state=present' 6 | with_items: 7 | - "@Development tools" 8 | - tar 9 | - unzip 10 | - sudo 11 | - which 12 | when: ansible_os_family == 'RedHat' 13 | 14 | - name: Ensure build dependencies are installed (Debian). 15 | apt: 'name="{{ item }}" state=installed' 16 | with_items: 17 | - build-essential 18 | - unzip 19 | - tar 20 | - sudo 21 | when: ansible_os_family == 'Debian' 22 | 23 | roles: 24 | - role_under_test 25 | -------------------------------------------------------------------------------- /vars/Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | network_pkgs: 3 | - python-selinux 4 | - bridge-utils 5 | - ifenslave 6 | - iproute2 7 | 8 | net_path: "/etc/network/interfaces.d" 9 | -------------------------------------------------------------------------------- /vars/RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | network_pkgs: 3 | - libselinux-python 4 | - bridge-utils 5 | - iputils 6 | 7 | net_path: "/etc/sysconfig/network-scripts" 8 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | env: 3 | RUNLEVEL: 1 4 | --------------------------------------------------------------------------------