Cisco CDP configuration with Ansible
Some Cisco IOS configuration settings are half-baked like the CDP settings for interfaces.
If you disable cdp for a interface you specify no cdp enable
. This setting will show up in the running config.
To re-enable: cdp enable
but this setting will NOT show up in the running config.
If an interface has cdp enabled there won’t be any cdp enable
config setting be present - even with show run all
.
Here is how I dealt with this situation.
Data
I have following data:
1
2
3
4
5
6
7
8
9
10
11
12
devices:
workstation:
linux-1: { name: 'linux-1', user: 'test1', ip_addr: '10.0.20.3' }
linux-2: { name: 'linux-2', user: 'test2', ip_addr: '10.0.20.4' }
laptop:
nb-linux-1: { name: 'nb-linux-1', user: 'test1', ip_addr: '10.0.30.10' }
nb-linux-2: { name: 'nb-linux-2', user: 'test1', ip_addr: '10.0.30.11' }
access-points:
wifi-ap-01: { name: 'wifi-ap-01', ip_addr: '10.0.100.10' }
wifi-ap-02: { name: 'wifi-ap-02', ip_addr: '10.0.100.11' }
server:
hv-vm-01: { name: 'hv-vm-01', ipmi: { name: 'hv-vm-01-ipmi', ip_addr: '10.0.100.20' } }
The data for the interface configuration looks like this:
1
2
3
4
5
6
7
8
# host_vars/swi-acs-01.yml
# the numbers are the port numbers - 1 = Gi1/0/1, 2 = Gi1/0/2
switch_interface_hash:
1: { device: "{{ devices['workstation']['linux-1'] }}" }
2: { device: "{{ devices['workstation']['linux-2'] }}" }
3: { device: "{{ devices['access-points']['wifi-ap-01'] }}" }
4: { switchport_enabled: false }
5: { device: "{{ devices['server']['hv-vm-01']['ipmi'] }}" }
Enable CDP globally
I will get the running config first ‘cause this will speed up later tasks
1
2
3
4
5
6
7
8
9
10
- name: get running-config
ios_config:
backup: true
defaults: true
register: running_config_backup_result
- name: enable cdp on switch
ios_config:
lines: 'cdp run'
running_config: "{{ lookup('file', running_config_backup_result['backup_path']) }}"
Get CDP settings
This command shows the CDP state of all interfaces.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
swi-acs-01#show cdp interface
CDP is not enabled on interface FastEthernet0
GigabitEthernet1/0/1 is up, line protocol is up
Encapsulation ARPA
Sending CDP packets every 60 seconds
Holdtime is 180 seconds
CDP is not enabled on interface GigabitEthernet1/0/2
GigabitEthernet1/0/3 is up, line protocol is up
Encapsulation ARPA
Sending CDP packets every 60 seconds
Holdtime is 180 seconds
CDP is not enabled on interface GigabitEthernet1/0/4
CDP is not enabled on interface GigabitEthernet1/0/5
CDP is not enabled on interface GigabitEthernet1/0/6
CDP is not enabled on interface GigabitEthernet1/0/7
CDP is not enabled on interface GigabitEthernet1/0/8
CDP is not enabled on interface GigabitEthernet1/0/9
CDP is not enabled on interface GigabitEthernet1/0/10
I will register this output for later use.
1
2
3
4
5
- name: get cdp interface settings
ios_command:
commands: 'show cdp interface'
register: check_cdp_interface
changed_when: false
Disable CDP on interface
When the device doesn’t process CDP packets disable it.
Some devices like the Cisco Access-Points or the IPMI/BMC of the Cisco UCS server’s do understand the protocol. For them we need to skip this setting and this is done via the last when statement.
{% raw %}
1
2
3
4
5
6
7
8
9
- name: disable cdp on interface
ios_config:
lines: 'no cdp enable'
parents: "interface GigabitEthernet1/0/{{ item.key }}"
running_config: "{{ lookup('file', running_config_backup_result['backup_path']) }}"
loop: "{{ switch_interface_hash | dict2items | default({}) }}"
when:
- item.value.switchport_enabled is undefined
- not item.value.device.name | regex_search('^(wifi-ap-\d+|hv-vm-\d+-ipmi)') # exclude some devices
{% endraw %}
Enable CDP on interface
To ensure that CDP is enabled on the desired interfaces we will use the registered output from before.
{% raw %}
1
2
3
4
5
6
7
8
9
10
- name: enable cdp on interface
ios_config:
lines: 'cdp enable'
parents: "interface GigabitEthernet1/0/{{ item.key }}"
running_config: "{{ lookup('file', running_config_backup_result['backup_path']) }}"
loop: "{{ switch_interface_hash | dict2items | default({}) }}"
when:
- item.value.switchport_enabled is undefined
- item.value.device.name | regex_search('^(wifi-ap-\d+|hv-vm-\d+-ipmi)')
- '"CDP is not enabled on interface GigabitEthernet1/0/" ~ item.key ~ "\n\n" in check_cdp_interface.stdout[0]'
{% endraw %}
It would be also possible and maybe a little bit more cleaner to iterate over all interfaces and execute the command show cdp interface <INTERFACE>
and then parse the output but it would be also slower.