Write a playbook containing tasks to configure specific settings on specific devices using conditions and loops, and verify the device state before and after configuration.
Outcomes
Create a playbook that configures interfaces by looping over variable list items.
As the student user on the workstation machine, use the lab command to prepare your system for this exercise.
This command also creates a project directory with the files needed for the exercise.
[student@workstation ~]$ lab start task-loops
Instructions
Open the /home/student/task-loops directory in VS Code and then create the group_vars/ios/interfaces.yml file to store interface information about the Cisco IOS managed nodes.
Open VS Code and click → .
Navigate to → and click .
If prompted, select , and then click .
Create the group_vars/ios/interfaces.yml file with the following content:
---
interfaces:
iosxe1.lab.example.com:
- name: Loopback0
description: Managed by Ansible
enabled: true
ipv4: "10.10.10.10/32"
- name: GigabitEthernet2
description: Managed by Ansible
enabled: true
ipv4: "172.25.150.20/24"
iosxe2.lab.example.com:
- name: Loopback0
description: Managed by Ansible
enabled: true
ipv4: "10.10.20.10/32"
- name: GigabitEthernet2
description: Managed by Ansible
enabled: true
ipv4: "172.25.150.21/24"This step intentionally omits configuring the GigabitEthernet1 interfaces.
Configuring the GigabitEthernet1 interfaces incorrectly might result in you being unable to connect to the iosxe1.lab.example.com or iosxe2.lab.example.com managed nodes.
If this happens, then you might need to recreate your lab environment.
Create the configure_interfaces.yml playbook in the /home/student/task-loops directory.
This playbook loops through the interfaces defined in the group_vars/ios/interfaces.yml file.
Create the configure_interfaces.yml playbook and target managed nodes in the ios inventory group.
Add a task to gather interface facts and a second task that displays the content of the ansible_facts['net_interfaces'] variable:
---
- name: Configure Cisco IOS interfaces
hosts: ios
gather_facts: false
tasks:
- name: Gather interface facts (pre)
cisco.ios.ios_facts:
gather_subset:
- interfaces
- name: Show ansible_facts['net_interfaces'] (pre)
ansible.builtin.debug:
var: ansible_facts['net_interfaces']Add a task to the end of the play that uses the cisco.ios.ios_interfaces module to configure basic interface information.
This task must ensure that an interface with the specified name exists.
The task might add a description to the interface and either enables or disables the interface.
...output omitted... - name: Configure basic interface information when:- interfaces is defined - interfaces[inventory_hostname] is defined cisco.ios.ios_interfaces: config: - name: "{{ item['name'] }}"
description: "{{ item['description'] | default(omit) }}"
enabled: "{{ item['enabled'] | default(false) }}"
state: merged loop: "{{ interfaces[inventory_hostname] }}"
The playbook implicitly includes variables in the | |
The list item must define the | |
If the list item does not define the | |
If the list item does not define the | |
The task loops through elements of the |
Add a task to the end of the play that uses the cisco.ios.ios_l3_interfaces module to configure IPv4 addresses for the defined interfaces.
In addition to the conditions in the previous task, Ansible only runs this second task if the list item defines the ipv4 variable:
...output omitted...
- name: Configure L3 interface information
when:
- interfaces is defined
- interfaces[inventory_hostname] is defined
- item['ipv4'] is defined
cisco.ios.ios_l3_interfaces:
config:
- name: "{{ item['name'] }}"
ipv4:
- address: "{{ item['ipv4'] }}"
state: merged
loop: "{{ interfaces[inventory_hostname] }}"Add a task to the end of the play that pauses the play for five seconds. This pause allows time for the interface to come up before querying for interface facts again. You only need to run the task once rather that once for each managed node.
...output omitted...
- name: Pause 5 seconds
ansible.builtin.pause:
seconds: 5
run_once: trueAdd two tasks to the end of the play to gather interface facts and display the content of the ansible_facts['net_interfaces'] variable.
If you copy and paste the first two task in the play, then change pre to post for the final two tasks.
The entire playbook consists of the following content:
---
- name: Configure Cisco IOS interfaces
hosts: ios
gather_facts: false
tasks:
- name: Gather interface facts (pre)
cisco.ios.ios_facts:
gather_subset:
- interfaces
- name: Show ansible_facts['net_interfaces'] (pre)
ansible.builtin.debug:
var: ansible_facts['net_interfaces']
- name: Configure basic interface information
when:
- interfaces is defined
- interfaces[inventory_hostname] is defined
cisco.ios.ios_interfaces:
config:
- name: "{{ item['name'] }}"
description: "{{ item['description'] | default(omit) }}"
enabled: "{{ item['enabled'] | default(false) }}"
state: merged
loop: "{{ interfaces[inventory_hostname] }}"
- name: Configure L3 interface information
when:
- interfaces is defined
- interfaces[inventory_hostname] is defined
- item['ipv4'] is defined
cisco.ios.ios_l3_interfaces:
config:
- name: "{{ item['name'] }}"
ipv4:
- address: "{{ item['ipv4'] }}"
state: merged
loop: "{{ interfaces[inventory_hostname] }}"
- name: Pause 5 seconds
ansible.builtin.pause:
seconds: 5
run_once: true
- name: Gather interface facts (post)
cisco.ios.ios_facts:
gather_subset:
- interfaces
- name: Show ansible_facts['net_interfaces'] (post)
ansible.builtin.debug:
var: ansible_facts['net_interfaces']Run the configure_interfaces.yml playbook.
Switch to the tab in VS Code, or change to the /home/student/task-loops directory in a GNOME terminal.
Run the playbook:
[student@workstation task-loops]$ ansible-navigator run configure_interfaces.yml
...output omitted...Scroll back through the playbook output and notice the following in the Show ansible_facts['net_interfaces'] (pre) task for each managed node.
The GigabitEthernet1 and GigabitEthernet2 interfaces do not have descriptions.
The GigabitEthernet1 interface already has an IPv4 addresses.
The GigabitEthernet2 interface does not have an IPv4 address and displays the administratively down operational status.
The Loopback0 interface does not exist.
The ansible-navigator.yml file in this project enables playbook artifacts.
If desired, you can review the output of the playbook using the ansible-navigator replay command.
You might select the artifact file name using tab completion.
You might also consider using the -m interactive option so that you can selectively view the output of specific tasks.
For example:
[student@workstation task-loops]$ansible-navigator replay -m interactive \configure_interfaces-artifact-2023-08-14T13\:58\:15.922542+00\:00.json
Scroll back through the playbook output and notice that the Configure basic interface information task performed the following tasks:
Added the Loopback0 interface to both managed nodes
Added the Managed by Ansible description to each Loopback0 and GigabitEthernet2 interface
Did not add a description to the GigabitEthernet1 interfaces because the interfaces.yml file does not define the GigabitEthernet1 interfaces
Enabled the GigabitEthernet2 interface on both managed nodes
Scroll back through the playbook output and notice that the Configure L3 interface information task performed the following tasks:
Added IPv4 addresses to each Loopback0 interface
Added IPv4 addresses to each GigabitEthernet2 interface
Scroll back through the playbook output and notice the following in the Show ansible_facts['net_interfaces'] (post) task for each managed node.
You can see the added descriptions for the Loopback0 and GigabitEthernet2 interfaces.
You can see the added IPv4 addresses for the Loopback0 and GigabitEthernet2 interfaces.
You can see that the GigabitEthernet2 interface displays the up operational status.
If either GigabitEthernet2 interface displays the down operational status, then the playbook probably did not wait long enough before querying for interface information.
Run the query_interfaces.yml playbook to display interface facts without making any changes.
Each GigabitEthernet2 interface should display the up operational status.
[student@workstation task-loops]$ ansible-navigator run query_interfaces.yml
...output omitted...Click → in VS Code to close the /home/student/task-loops directory, or run the cd command in a GNOME terminal to return to the student home directory:
[student@workstation task-loops]$ cd