cisco.ios
cisco.ios copied to clipboard
add vrf support to L3 interfaces
SUMMARY
Adds VRF support to L3 interfaces
- Include VRF info in Facts. Fixes #653
- VRF Interface assignment
- Optional restoration of removed commands
- Legacy support
ISSUE TYPE
- Feature Pull Request
COMPONENT NAME
ios.ios_l3_interfaces ios.ios_vrf
ADDITIONAL INFORMATION
Background
Ok, trying to be brief. I was recently tasked by a customer of mine to automate changing vrfs on interfaces on hundres of routers. The interfaces were to keep same addressing and configuration as before the vrf change.
I find there's a lot regarding VRFS that I feel is missing so I updated ios.l3_interfaces in my fork with features necessary to complete the task. I'm now putting this up here for review and debate in case there's any interest of having some isotope of it merged
The features I've added or modified are:
FACTS
As far as I can see, neither ios_vrf or l3_interfaces provides VRF facts. This is kind of surprising since a large number of routers today, if not most of them, use vrfs. ios.l3_interfaces provides ip adressing information, but not vrf information. Addng vrfs to the l3_interfaces facts will make the module much more attractive and useable.
VRF INTERFACE CONFIGURATION
My original plan was to be a slacker and not do anything beyond the facts since ios.ios_vrf already has the option to assign vrfs to interfaces. But after some pondering I concluded that it doesn't sit right that interface assignment is handled by ios.ios_vrf. My humble opinion is that ios.ios_vrf should handle vrf definitions and ios.l3_interfaces should handle assignments. This would more correctly reflect how vrfs are configured on routers as well.
Example:
# Not like this. Not to critize though, its very convenient :)
- name: assign interface to vrf
cisco.ios.ios_vrf:
name: test_vrf
interfaces:
- GigabitEthernet5
# Proper way. IMHO
- name: vrf definition
cisco.ios.ios_vrf:
name: test_vrf
- name: apply to interface
ios_l3_interfaces:
config:
- name: GigabitEthernet5
vrf: test_vrf
state: merged
RESTORATION
Changing vrfs on interfaces removes the assigned ip address and ip addresses used for FHRP (HSRP,GLBP), multicast/igmp-joins etc. I noticed that ios.ios_vrf automatically reapplies/restores the ip/ipv6 address(es) when assigning vrfs to interfaces, BUT this automacy contradicts Ciscos behavior of removing the configuration in the first place. Not removing this configuration could in fact be quite dangerous. At least in theory.
It's very convenient that addresses are restored, but it should be a choice made by the user, due to the potential risk involved. In addition, ios.ios_vrf restores the ip/ipv6 address command, but it does not restore other removed commands like the HSRP address. After some back and forth I ended up implementing a code that follows the following principles for restoration
- Automatically restore configuration that is part of the play/intent. Makes sense!
- Do not restore commands negated by the play. Well, Duh...
- Restore commands only if the restore_commands option is set, which defaults to false to "comply" with Cisco behavior. Ha!
This is probably better explained by example:
# Before state
interface GigabitEthernet5
ip address 192.168.0.2 255.255.255.0
ip address 169.254.1.2 255.255.255.0 secondary
ipv6 address 2001:db8::1/64
standby 1 ip 192.168.0.1
# Play
- name: apply to interface
ios_l3_interfaces:
restore_commands: false
config:
- name: GigabitEthernet5
vrf: test_vrf
ipv4:
- address: 192.168.0.2/24
ipv6:
- address: 2001:db8::1/64
state: merged
# After state
interface GigabitEthernet5
vrf forwarding test_vrf
ip address 192.168.0.2 255.255.255.0
ipv6 address 2001:db8::1/64
The remote_command option is set to false (default), but the primary ip/ipv6 addresses are still restored since they are part of the play. The secondary & hsrp addresses are not restored. Running the same play with restore_commands set to true would restore all commands.
LEGACY SUPPORT
There are two ways to configure vrfs. vrf definition
vs ip vrf
. The latter, is considered legacy, and does not support ipv6, but there might be alot of peeps out there who still use the legacy way for various reasons. To complicate things further, the legacy way has the possibility of running ipv4 in a vrf and ipv6 globally. Finally, I can't find any documentation at cisco where they mention they plan to deprecate the legacy way so decided to add support for this as well.
Legacy way breaks the symbiosis with ios.ios_vrf since that module uses vrf definition
. A vrf created using vrf definition
, MUST use vrf forwarding when applied to an interface. A vrf created using ip vrf
, MUST use ip vrf forwarding
. IOS returns an error if the oposite is attempted.
I guess legacy way could be used for migrating to the new syntax, but Cisco already has a command for this called vrf upgrace-cli
. This command does not merge ipv6 into the vrf though.
Hmm, I just realised that I might have just argued myself away from implementing this, but it's already done so here's an example using legacy way
# Before state
interface GigabitEthernet5
ip address 192.168.0.2 255.255.255.0
ipv6 address 2001:db8::1/64
standby 1 ip 192.168.0.1
# Play
- name: apply to interface
ios_l3_interfaces:
restore_commands: false
config:
- name: GigabitEthernet5
ipv4:
- vrf test_vrf
- address: 192.168.0.2/24
state: merged
# After state
interface GigabitEthernet5
ip vrf forwarding test_vrf
ip address 192.168.0.2 255.255.255.0
ipv6 address 2001:db8::1/64
Pay attention to the ipv6 address. It was not part of the play and restore_commands is set to false, yet it's still present! Since ip vrf forwarding does not support ipv6, the ipv6 address is not removed when the vrf is applied. This interface now operates ipv4 in the test_vrf routing table and ipv6 in global routing table.
Build failed.
:heavy_check_mark: ansible-galaxy-importer SUCCESS in 4m 03s :heavy_check_mark: build-ansible-collection SUCCESS in 4m 13s :x: ansible-ee-integration-ios-latest FAILURE in 16m 55s (non-voting) :x: ansible-ee-integration-ios-stable-2.9 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-stable-2.11 FAILURE in 17m 28s (non-voting) :x: ansible-ee-integration-ios-stable-2.12 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-libssh-latest FAILURE in 44m 56s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.9 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.11 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.12 FAILURE in 43m 14s (non-voting) :x: ansible-tox-linters FAILURE in 5m 07s
Build succeeded.
:heavy_check_mark: ansible-galaxy-importer SUCCESS in 4m 51s :heavy_check_mark: build-ansible-collection SUCCESS in 4m 33s :x: ansible-ee-integration-ios-latest NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-stable-2.9 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-stable-2.11 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-stable-2.12 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-libssh-latest NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.9 FAILURE in 45m 53s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.11 FAILURE in 50m 13s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.12 NODE_FAILURE in 0s (non-voting) :heavy_check_mark: ansible-tox-linters SUCCESS in 5m 34s
Build succeeded.
:heavy_check_mark: ansible-galaxy-importer SUCCESS in 4m 38s :heavy_check_mark: build-ansible-collection SUCCESS in 4m 02s :x: ansible-ee-integration-ios-latest FAILURE in 14m 24s (non-voting) :x: ansible-ee-integration-ios-stable-2.9 FAILURE in 14m 53s (non-voting) :x: ansible-ee-integration-ios-stable-2.11 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-stable-2.12 FAILURE in 14m 23s (non-voting) :x: ansible-ee-integration-ios-libssh-latest FAILURE in 43m 20s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.9 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.11 NODE_FAILURE in 0s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.12 NODE_FAILURE in 0s (non-voting) :heavy_check_mark: ansible-tox-linters SUCCESS in 4m 58s
Codecov Report
Merging #723 (25ad75c) into main (9e2218f) will decrease coverage by
0.37%
. The diff coverage isn/a
.
Additional details and impacted files
@@ Coverage Diff @@
## main #723 +/- ##
==========================================
- Coverage 85.84% 85.47% -0.37%
==========================================
Files 184 184
Lines 11879 11949 +70
==========================================
+ Hits 10198 10214 +16
- Misses 1681 1735 +54
Build succeeded. https://ansible.softwarefactory-project.io/zuul/buildset/6118a87e37c44d0f8c1c7e3104b4c6e7
:heavy_check_mark: ansible-galaxy-importer SUCCESS in 4m 54s :heavy_check_mark: build-ansible-collection SUCCESS in 8m 40s :x: ansible-ee-integration-ios-latest FAILURE in 13m 37s (non-voting) :x: ansible-ee-integration-ios-stable-2.9 FAILURE in 13m 45s (non-voting) :x: ansible-ee-integration-ios-stable-2.11 FAILURE in 13m 24s (non-voting) :x: ansible-ee-integration-ios-stable-2.12 FAILURE in 13m 46s (non-voting) :x: ansible-ee-integration-ios-libssh-latest FAILURE in 13m 35s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.9 FAILURE in 14m 01s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.11 FAILURE in 14m 34s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.12 FAILURE in 14m 43s (non-voting) :heavy_check_mark: ansible-tox-linters SUCCESS in 10m 09s
Build succeeded. https://ansible.softwarefactory-project.io/zuul/buildset/32baf35993964b199f105e9e5c27d00d
:heavy_check_mark: ansible-galaxy-importer SUCCESS in 4m 48s :heavy_check_mark: build-ansible-collection SUCCESS in 8m 36s :x: ansible-ee-integration-ios-latest FAILURE in 14m 29s (non-voting) :x: ansible-ee-integration-ios-stable-2.9 FAILURE in 17m 40s (non-voting) :x: ansible-ee-integration-ios-stable-2.11 FAILURE in 13m 16s (non-voting) :x: ansible-ee-integration-ios-stable-2.12 FAILURE in 12m 47s (non-voting) :x: ansible-ee-integration-ios-libssh-latest FAILURE in 13m 15s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.9 FAILURE in 15m 29s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.11 FAILURE in 14m 55s (non-voting) :x: ansible-ee-integration-ios-libssh-stable-2.12 FAILURE in 14m 59s (non-voting) :heavy_check_mark: ansible-tox-linters SUCCESS in 10m 12s
Closing this PR as per the conversation above.