Skip to content

Commit f6d8f5a

Browse files
authored
Merge pull request #3 from harrytruman/wip_adam
2 parents 0ccbadf + e91db6e commit f6d8f5a

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

README.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,15 @@ And if you want to restore these configs, just grab the most recent backup file:
196196
src: /var/tmp/backup/{{ ansible_network_os }}-{{inventory_hostname}}.cfg
197197
```
198198

199+
Another option to restore a config is to pull the last cached fact for the device. This is a great use case for rolling out some changes, validating and having a rollback if the validation fails.
200+
201+
This variable is stored as "ansible_net_config" and contains the entire running config:
202+
203+
```
204+
- name: restore config
205+
ios_config:
206+
src: "{{ ansible_net_config }}"
207+
```
199208
--------------
200209

201210
### Configs, Commands, and Templates
@@ -223,6 +232,129 @@ However, you may eventually run into a situation where you need to add/remove AA
223232

224233
Ansible's [Network Resource Modules](https://docs.ansible.com/ansible/latest/network/user_guide/network_resource_modules.html) are the solution to managing device states across different devices and different device types. NRMs already have the logic built in to know how config properties need to be orchestrated in which specific ways, and these modules know how to run the behind-the-scenes commands that get you the desired configuration state.
225234

235+
For a deep dive into Resource Modules, my colleague [Trishna did a wonderful talk at Ansiblefest 2019](https://www.ansible.com/deep-dive-into-ansible-network-resource-module).
236+
237+
238+
### Blocks and Error Handling
239+
240+
#### Blocks
241+
242+
There comes a time in a playbook where you want to have Ansible execute multiple tasks based off of a condition such as "if this variable exists".
243+
244+
Below is an example how many people do this starting out:
245+
246+
```
247+
- name: Configure Interface Settings
248+
cisco.nxos.nxos_interfaces:
249+
config: "{{ port_config }}"
250+
state: replaced
251+
when: interface_config is defined
252+
253+
- name: Configure Port Channels
254+
cisco.nxos.nxos_lag_interfaces:
255+
config: "{{ portchannel_config }}"
256+
state: replaced
257+
when: interface_config is defined
258+
259+
- name: Configure VLANs on Trunk Interfaces
260+
cisco.nxos.nxos_l2_interfaces:
261+
config: "{{ trunk_config }}"
262+
state: replaced
263+
when: interface_config is defined
264+
265+
- name: Configure VLANs on Access Interfaces
266+
cisco.nxos.nxos_l2_interfaces:
267+
config: "{{ access_config }}"
268+
state: replaced
269+
when: interface_config is defined
270+
271+
```
272+
273+
Notice the "when: interface_config is defined" after each task. This get's repetitve and makes the playbook messy, especially if you have multiple other tasks that apply to the conditional statemtent.
274+
275+
Enter the [Block and Rescue](https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html) operations.
276+
277+
Let's take a look at an example that uses block to consolidate these tasks:
278+
279+
```
280+
281+
- name: Configure Cisco NXOS Interfaces
282+
block:
283+
- name: Configure Interface Settings
284+
cisco.nxos.nxos_interfaces:
285+
config: "{{ port_config }}"
286+
state: replaced
287+
288+
- name: Configure Port Channels
289+
cisco.nxos.nxos_lag_interfaces:
290+
config: "{{ portchannel_config }}"
291+
state: replaced
292+
293+
- name: Configure VLANs on Trunk Interfaces
294+
cisco.nxos.nxos_l2_interfaces:
295+
config: "{{ trunk_config }}"
296+
state: replaced
297+
298+
- name: Configure VLANs on Access Interfaces
299+
cisco.nxos.nxos_l2_interfaces:
300+
config: "{{ access_config }}"
301+
state: replaced
302+
when: interface_config is defined
303+
```
304+
305+
Now the block of tasks only execute if the "interface_config" variable is defined, simple right?
306+
307+
#### Error Handling
308+
309+
Now that we covered Blocks let's discuss Rescue as well. If you are familiar with Python think of this as try/except where you can perform a check or task on the try block and catch any errors and handle the output or action in the except block.
310+
311+
Let's take a really simple example of configuring a VLAN with an incorrect VLAN ID. We are doing this intentionally to break the task:
312+
313+
```
314+
---
315+
- name: Configure VLANS
316+
hosts: nexus1
317+
gather_facts: no
318+
319+
vars:
320+
vlans:
321+
- name: DEV
322+
vlan_id: "10"
323+
- name: INVALID
324+
vlan_id: "ABC"
325+
326+
tasks:
327+
- name: Configure Cisco NXOS VLANs
328+
block:
329+
- name: Configure VLANs Settings
330+
nxos_vlans:
331+
config: "{{ vlans }}"
332+
state: merged
333+
334+
rescue:
335+
- name: Debug VLANs for troubleshooting
336+
debug:
337+
msg: "Error configuring VLANs for host {{ inventory_hostname }}, here are the VLANs that were specified:\n {{ vlans }}"
338+
```
339+
340+
Here is the output, as expected the task broke because the VLAN "ABC" is not an integer:
341+
342+
```
343+
TASK [Configure VLANs Settings] *****************************************************************************************************************************************************************
344+
fatal: [nexus1]: FAILED! => changed=false
345+
msg: 'argument vlan_id is of type <type ''str''> found in ''config''. and we were unable to convert to int: <type ''str''> cannot be converted to an int'
346+
347+
TASK [Debug VLANs for troubleshooting] *****************************************************************************************************************************************************************
348+
ok: [nexus1] =>
349+
msg: |-
350+
Error configuring VLANs for host nexus1, here are the VLANs that were specified:
351+
[{'name': 'DEV', 'vlan_id': '10'}, {'name': 'INVALID', 'vlan_id': 'ABC'}]
352+
353+
PLAY RECAP *****************************************************************************************************************************************************************
354+
nexus1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
355+
````
356+
357+
One thing to keep in mind is that the task above will show up as OK and not failed.
226358
For a practical example, here’s an interface template:
227359
228360
```

0 commit comments

Comments
 (0)