You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
+
```
199
208
--------------
200
209
201
210
### Configs, Commands, and Templates
@@ -223,6 +232,129 @@ However, you may eventually run into a situation where you need to add/remove AA
223
232
224
233
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.
225
234
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:
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:
PLAY RECAP *****************************************************************************************************************************************************************
0 commit comments