Skip to content

Instantly share code, notes, and snippets.

@platu
Last active February 19, 2024 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save platu/15d433b3a63b6ba77b45db425b34e2f0 to your computer and use it in GitHub Desktop.
Save platu/15d433b3a63b6ba77b45db425b34e2f0 to your computer and use it in GitHub Desktop.
DevNet Lab 14 – Use Ansible to Back Up and Configure a Router
tags
m1, devnet, cisco, linux, lab14

DevNet Lab 14 -- Use Ansible to Back Up and Configure a Router

[toc]


Background / Scenario

In this lab, you will explore the fundamentals of how to use Ansible to automate some basic device management task. First, you will configure Ansible in your devnet VM. Next, you will use Ansible to connect to the virtual router and back up its configuration. Finally, you will configure this virtual router with IPv6 addressing.

Part 1: Configure Ansible on the Devnet VM

In this part, you will configure Ansible to run from a specific directory.

Step 1: Create the Ansible directory and configuration file

  1. Make the ~/labs/lab14 directory for example and navigate to this folder

    mkdir -p ~/labs/lab14 && cd ~/labs/lab14
  2. Check that ansible package is installed

    If the ansible package is not already installed on your Devnet VM, it's time to do so.

    apt show ansible | head -n 10
    Package: ansible
    Version: 7.7.0+dfsg-3
    Priority: optional
    Section: universe/admin
    Origin: Ubuntu
    Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
    Original-Maintainer: Lee Garrett <debian@rocketjump.eu>
    Bugs: https://bugs.launchpad.net/ubuntu/+filebug
    Installed-Size: 263 MB
    Depends: ansible-core (>= 2.11.5-1~), python3:any, openssh-client | python3-paramiko (>= 2.6.0), python3-distutils, python3-dnspython, python3-httplib2, python3-jinja2, python3-netaddr, python3-yaml
    
  3. Create a new ansible.cfg file in the lab14 directory from the shell prompt

    cat << 'EOF' > ansible.cfg
    # config file for Lab 14 virtual router management
    [defaults]
    # Use inventory/ folder files as source
    inventory=inventory/
    host_key_checking = False # Don't worry about RSA Fingerprints
    retry_files_enabled = False # Do not create them
    deprecation_warnings = False # Do not show warnings
    interpreter_python = /usr/bin/python3
    [inventory]
    enable_plugins = auto, host_list, yaml, ini, toml, script
    [persistent_connection]
    command_timeout=100
    connect_timeout=100
    connect_retry_timeout=100
    ssh_type = libssh
    EOF
    
  4. Ensure that all necessary libraries and collections are up to date.

    • Add the Python bindings to client functionality of libssh specific to Ansible use case

      pip3 install ansible-pylibssh --break-system-packages

      :::info As long as we use Ansible provided by a package, we cannot mix with a Python virtual environment. This is the reason why we choose to install the Python ansible-pylibssh library with the pip3 command outside of a virtual environment with the --break-system-packages option. :::

    • Update Cisco Ansible collection to the lastest version

      ansible-galaxy collection install -f cisco.ios

      The local collections have priority over the system collection.

      ansible-galaxy collection list
      # /home/etu/.ansible/collections/ansible_collections
      Collection        Version
      ----------------- -------
      ansible.netcommon 6.0.0  
      ansible.utils     3.1.0  
      cisco.ios         6.1.2 
      
  5. Create the inventory directory

    mkdir ~/labs/lab14/inventory

    The contents of this directory will later be supplemented by the virtual router's connection parameters.

Step 2: Check SSH access from Devnet VM to virtual router VM

We start with a shell test connection before to set the configuration for ansible.

Be sure the virtual router is already up and running. If it's not the case, refer to DevNet Lab 13 – Run the Cisco IOS-XE router VM

One more time, be sure to change tap interface number to match your resource allocation.

ssh etu@fe80::baad:caff:fefe:XXX%enp0s1
The authenticity of host 'fe80::faad:caff:fefe:XXX%enp0s1 (fe80::faad:caff:fefe:XXX%enp0s1)' can't be established.
RSA key fingerprint is SHA256:e+oyegX4BzzQSKNVz7vjoi8psHTxUjIw/rc/44Y8tHY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'fe80::faad:caff:fefe:2%enp0s1' (RSA) to the list of known hosts.
(etu@fe80::faad:caff:fefe:XXX%enp0s1) Password: 

rtrXXX#

Step 3: Create a new Ansible vault file

  1. Create a new vault file called lab14_passwd.yml and enter the unique vault password which will be used for all users passwords to be stored.

    ansible-vault create $HOME/lab14_passwd.yml
    New Vault password:
    Confirm New Vault password:
    

    This will open the default editor which is defined by the $EDITOR environment variable. There we enter a variable name which will designate the password for Web server VM user account.

    ansible_user_passwd: 4n51bl3
  2. Create the ansible_user account on the IOS XE system of the CSR1000v

    Open a SSH connection to the virtual router and add a new user account with maximum privilege level and the same password as the one chosen for ansible vault.

    rtrXXX#conf terminal 
    Enter configuration commands, one per line.  End with CNTL/Z.
    rtrXXX(config)#user ansible_user privilege 15 secret 4n51bl3
    rtrXXX(config)#^Z
    rtrXXX#copy run start
    Destination filename [startup-config]? 
    Building configuration...
    [OK]
  3. Exit an open a new SSH connection with the ansible_user identity and list the IPv6 addresses of this router in order to fill the inventory file

    • First, complete your SSH config file in order to avoid identity conflicts on Local Link IPv6 addresses
    cat << EOF >> $HOME/.ssh/config
    
    Host fe80::*
    	CheckHostIP no
    	StrictHostKeyChecking no
    	UserKnownHostsFile=/dev/null
    EOF
    
    • Second, open the new SSH conection
    ssh ansible_user@fe80::faad:caff:fefe:XXX%enp0s1
    Warning: Permanently added 'fe80::faad:caff:fefe:2%enp0s1' (RSA) to the list of known hosts.
    (ansible_user@fe80::faad:caff:fefe:2%enp0s1) Password: 
    
    rtrXXX#sh users
        Line       User       Host(s)              Idle       Location
    *434 vty 0     ansible_us idle                 00:00:00 FE80::BAAD:CAFF:FEFE:0
    
      Interface    User               Mode         Idle     Peer Address
    
    rtrXXX#sh ipv6 int br GigabitEthernet 1
    GigabitEthernet1       [up/up]
        FE80::FAAD:CAFF:FEFE:2
        2001:678:3FC:1C:FAAD:CAFF:FEFE:2
    

    In the screen copy above, we have the choice between 2 IPv6 addresses : the Local Link address or the GUA address.

    :::info It is a good practise to have the DevNet VM and the Out of Band router interface located within the same VLAN. This is the reason why we choose to user le Local Link IPv6 address into the inventory file. :::

Step 4: Create the Ansible inventory file

Ansible uses an inventory file called hosts that contains device information used by Ansible playbooks.

In this lab you will run Ansible from the ansible directory. Therefore, you need separate hosts and ansible.cfg files for each lab.

:::info Note: The terms hosts file and inventory file are synonymous and will be used interchangeably throughout the Ansible labs. :::

The Ansible inventory file defines the devices and groups of devices that are used by the Ansible playbook. The file can be in one of many formats, including YAML and INI, depending on your Ansible environment.

The inventory file can list devices by IP address or fully qualified domain name (FQDN), and may include host specific parameters as well.

Create the inventory hosts.yml file in the inventory directory and add the following content to the file and save. All XXX marks have to be edited to designate your own CSR1000v VM instance.

cat << EOF > inventory/hosts.yml
ios:
  hosts:
    rtrXXX:
      ansible_host: 'fe80::faad:caff:fefe:XXX%enp0s1'
      ansible_port: 2222
  vars:
    ansible_ssh_user: ansible_user
    ansible_ssh_pass: '{{ ansible_user_passwd }}'
    ansible_connection: network_cli
    ansible_network_os: ios

all:
  children:
    ios:
EOF

The hosts.yml file begins with the [ios] section. This section lists aliases for a set of devices. Here we have a single alias: rtrXXX. An alias is used from within the Ansible playbook to reference a device designated by the ansible_host and ansible_port variables. Within the [ios] section, the hosts.yml file specifies a set of variables that will be used by the Ansible playbook to access the device. These are the SSH credentials Ansible needs to securely access the CSR1000v VM.

  • ansible_ssh_user is a variable containing the username used to connect to the remote device. Without this, the user that is running the ansible-playbook would be used.
  • ansible_ssh_pass is a variable containing the password for ansible_ssh_user. If not specified, the SSH key would be used.
  • ansible_connection specifies the library used for the connection to the en device.
  • ansible_network_os specifies the operating system used on the end device

Check the Ansible configuration and access to the router

  1. Use the ansible --version command to display version information.
ansible --version
ansible [core 2.14.13]
  config file = /home/etu/labs/lab14/ansible.cfg
  configured module search path = ['/home/etu/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/etu/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.11.8 (main, Feb  7 2024, 21:52:08) [GCC 13.2.0] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True
  1. Parse your own ansible.cfg file.

    Now, you need to edit your ansible.cfg file to look at the location of your hosts.yml inventory file.

    Open the ansible.cfg file and search lines referring to inventory.

    grep -A2 inventory ansible.cfg
    # Use inventory/ folder files as source
    inventory=inventory/
    host_key_checking = False # Don't worry about RSA Fingerprints
    retry_files_enabled = False # Do not create them
    --
    [inventory]
    enable_plugins = auto, host_list, yaml, ini, toml, script
    [persistent_connection]
    

    Like Python, the # is used for comments within the ansible.cfg file.

    If the entry refers to a file name such as inventory=inventory/ the comment cannot come after the entry. Ansible treats the # and the comment that follows as part of the filename. Therefore, in these cases, the # comment must be on a separate line.

    However, variables can have a comment on the same line as shown for host_key_checking and retry_files_enabled.

    The ansible.cfg file tells Ansible where to find the inventory file and sets certain default parameters. The information you entered in your ansible.cfg file is:

    • inventory=inventory/ - All your inventory files are in the inventory directory.
    • host_key_checking = False - The local development environment does not have SSH keys set up. You have set the host_key_checking set to False, which is the default. In a production network, host_key_checking would be set to True.
    • retry_files_enabled = False - When Ansible has problems running playbooks for a host, it will output the name of the host into a file in the current directory ending in .retry. To prevent clutter, it is common to disable this setting.

SUMMARY: Your Ansible configuration files.

In this Part, you configured Ansible to run in the ansible directory.

In this lab you need a ansible.cfg file in your ansible directory and an inventory file hosts.yml into the inventory directory.

  • You edited the hosts file to contain login and IP address information for the virtual router
  • You edited the ansible.cfg file to use the local hosts file as the inventory file

In the next Part, you will create a playbook to tell Ansible what to do.

Inventory status can be checked through the ansible-inventory command:

ansible-inventory --yaml --list
all:
  children:
    ios:
      hosts:
        rtrXXX:
          ansible_connection: network_cli
          ansible_host: fe80::faad:caff:fefe:XXX%enp0s1
          ansible_network_os: ios
          ansible_port: 2222
          ansible_ssh_pass: '{{ ansible_user_passwd }}'
          ansible_ssh_user: ansible_user
    ungrouped: {}

Connection to the router device can be checked through the Ansible ping module:

ansible -m ping all --ask-vault-pass --extra-vars '@$HOME/lab14_passwd.yml'
Vault password: 
rtrXXX | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Part 2: Use Ansible to Back up a Configuration

In this Part, you will create an Ansible playbook that will automate the process of backing up the configuration of the router. Playbooks are at the center of Ansible. When you want Ansible to get information or perform an action on a device or group of devices, you run a playbook to get the job done.

An Ansible playbook is a YAML file containing one or more plays. Each play is a collection of tasks.

  • A play is a matching set of tasks to a device or group of devices.
  • A task is a single action that references a module to run along with any input arguments and actions. These tasks can be simple or complex depending on the need for permissions, the order to run the tasks, and so on.

A playbook may also contain roles. A role is a mechanism for breaking a playbook into multiple components or files, simplifying the playbook and making it easier to reuse. For example, the common role is used to store tasks that can be used across all of your playbooks. Roles are beyond the scope of this lab.

The Ansible YAML playbook includes objects, lists and modules.

  • A YAML object is one or more key value pairs. Key value pairs are separated by a colon without the use of quotation marks, for example hosts: Router.
  • An object can contain other objects such as a list. YAML uses lists or arrays. A hypen "-" is used for each element in the list.
  • Ansible ships with a number of modules (called the module library) that can be executed directly on remote hosts or through playbooks. An example is the ios_command module used to send commands to an IOS device and return the results. Each task typically consists of one or more Ansible modules.

The ansible-playbook command uses parameters to specify:

  • The vault file which contains the credentials to decrypt in order to connect with the user acount given in the inventory file.
  • The playbook you want to run backup_cisco_router_playbook.yml

Step 1: Create your Ansible playbook.

The Ansible playbook is a YAML file. Make sure you use the proper YAML indentation. Every space and dash is significant. You may lose some formatting if you copy and paste the code in this lab.

  1. Create a new file in the ansible directory with the following name: backup_playbook.yml

  2. Add the following information to the file.

---
- name: AUTOMATIC BACKUP OF ROUTER CONFIGURATION
  hosts: ios
  tasks:
    - name: BACKUP RUNNING CONFIG
      cisco.ios.ios_config:
        backup: true
...

Step 2: Examine your Ansible playbook.

The playbook you have created contains one play with one task. The following is an explanation of your playbook:

  • --- This is at the beginning of every YAML file, which indicates to YAML that this is a separate document. Each file may contain multiple documents separated by ---
  • name: - This is the name of the play.
  • hosts: ios - This is the alias of the previously configured hosts.yml file. By referring to this alias in your playbook, the playbook can use all the parameters associated with this inventory file entry which includes IP address of the devices.
  • tasks: - This keyword indicates one or more tasks to be performed.

The task is to backup the router configuration.

  • cisco.ios.ios_config: - This is an Ansible module that is used to manage an IOS device configuration. The ios_config module belongs to the cisco.ios collection.

:::info Note: In the Linux terminal, you can use the ansible-doc module_name command to view the manual pages for any module and the parameters associated with that module. (e.g. ansible-doc cisco.ios.ios_command or ansible-doc cisco.ios.ios_config) :::

  • backup: - This parameter is associated with the ios_config module. It is used to list IOS commands in the playbook that are to be sent to the remote IOS device. The resulting output from the command is returned.

Step 3: Run the Ansible backup Playbook.

  1. In Part 1, you started the virtual VM. Ping it to verify you can reach it.

    ping -c2 fe80::faad:caff:fefe:XXX%enp0s1
    PING fe80::faad:caff:fefe:2%enp0s1(fe80::faad:caff:fefe:2%enp0s1) 56 data bytes
    64 bytes from fe80::faad:caff:fefe:2%enp0s1: icmp_seq=1 ttl=64 time=1.63 ms
    64 bytes from fe80::faad:caff:fefe:2%enp0s1: icmp_seq=2 ttl=64 time=0.939 ms
    
    --- fe80::faad:caff:fefe:2%enp0s1 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1002ms
    rtt min/avg/max/mdev = 0.939/1.282/1.625/0.343 ms
    
  2. Check if ansible has access to this router through its configuration file and inventory. The router hostname rtrXXX has to point on your own router in the inventory file.

    ansible -m ping all --ask-vault-pass --extra-vars '@$HOME/lab14_passwd.yml'
    Vault password:
    rtrXXX | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    
  3. Now you can run the Ansible playbook using the ansible-playbook command:

    ansible-playbook backup_playbook.yml --ask-vault-pass --extra-vars '@$HOME/lab14_passwd.yml'
    Vault password: 
    PLAY [AUTOMATIC BACKUP OF ROUTER CONFIGURATION] ************
    
    TASK [Gathering Facts] *************************************
    ok: [rtrXXX]
    
    TASK [BACKUP RUNNING CONFIG] *******************************
    changed: [rtrXXX]
    
    PLAY RECAP *************************************************
    rtrXXX     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    The PLAY RECAP should display ok=2 changed=1 indicating a successful playbook execution.

    If your Ansible playbook fails, some of the things to check in your playbook are:

    • Make sure your hosts.yml and ansible.cfg files are correct.
    • Make sure the YAML indentation is correct.
    • Make sure your IOS command is correct.
    • Check all the Ansible playbook syntax.
    • Verify you can ping the CSR1000v.

    If you continue to have problems:

    • Try typing one line at a time and running the playbook each time.
    • Check the inventory file content with the ansible-inventory command:
    ansible-inventory --yaml --list
    all:
      children:
        ios:
          hosts:
            rtrXXX:
              ansible_connection: network_cli
              ansible_host: fe80::faad:caff:fefe:XXX%enp0s1
              ansible_network_os: ios
              ansible_port: 2222
              ansible_ssh_pass: '{{ ansible_user_passwd }}'
              ansible_ssh_user: ansible_user
    

Step 4: Verify the backup file has been created.

List files in the backup folder and open the most recent file. You can also use the head command to print the first lines of the backup file. You now have a backup of the router configuration.

ls -A backup
rtrXXX_config.2024-02-17@09:16:51
head -n 20 backup/rtrXXX_config.2024-02-17@09\:16\:51 
Building configuration...

Current configuration : 7172 bytes
!
! Last configuration change at 08:38:06 WEST Sat Feb 17 2024 by etu
! NVRAM config last updated at 08:46:09 WEST Sat Feb 17 2024 by ansible_user
!
version 17.13
service timestamps debug datetime msec
service timestamps log datetime localtime show-timezone
platform qfp utilization monitor load 80
platform punt-keepalive disable-kernel-core
platform sslvpn use-pd
platform console serial
!
hostname rtrXXX
!
boot-start-marker
boot-end-marker
!

Part 3: Use Ansible to Configure a Device

In this Part, you will create another Ansible playbook to configure IPv6 addressing on the CSR1000v router.

Step 1: View your hosts inventory file.

Re-examine your hosts.yml inventory file. As a reminder, this file contains the alias Router and three inventory variables for the username, password, and host IP address. The playbook for this Part will also use this file and the ansible.cfg file you created early in the lab.

cat inventory/hosts.yml

Step 2: Create a new playbook.

  1. Create a subdirectory named trace which will receive the playbook results.

    mkdir trace
    mkdir: created directory 'trace'
  2. Create a subdirectory named host_vars which will store variables of any device named in the inventory

    mkdir host_vars
    mkdir: created directory 'host_vars'
  3. Create a new YAML file in the host_vars directory with the device name: rtrXXX.yml

---
rtr_id: XXX

vlans:
  red:
    vlan_id: 100
  purple:
    vlan_id: 101
  blue:
    vlan_id: 102

interface: GigabitEthernet2

subinterfaces:
  red:
    name: 'RED VLAN SUBINTERFACE'
    dot1q: '{{ vlans["red"]["vlan_id"] | int }}'
    addr: '2001:678:3fc:{{ "%x" % vlans["red"]["vlan_id"] | int }}::{{ "%x" % rtr_id | int }}/64'
  purple:
    name: 'PURPLE VLAN SUBINTERFACE'
    dot1q: '{{ vlans["purple"]["vlan_id"] | int }}'
    addr: '2001:678:3fc:{{ "%x" % vlans["purple"]["vlan_id"] | int }}::{{ "%x" % rtr_id | int }}/64'
  blue:
    name: 'BLUE VLAN SUBINTERFACE'
    dot1q: '{{ vlans["blue"]["vlan_id"] | int }}'
    addr: '2001:678:3fc:{{ "%x" % vlans["blue"]["vlan_id"] | int }}::{{ "%x" % rtr_id | int}}/64'
...
  1. Create a new file named router_config_playbook.yml

  2. Add the following information to the file. Make sure you use the proper YAML indentation. Every space and dash is significant. You may lose some formatting if you copy and paste.

---
- name: VLAN SUBINTERFACES CONFIGURATION
  hosts: all

  tasks:
    - name: VARS ANALYSIS
      ansible.builtin.debug:
        msg:
          - "vlan: {{ item.dot1q }} --> address: {{ item.addr }}"
          - "Network: {{ item.addr | ipv6 | ipaddr('network') }}/{{ item.addr | ipv6 | ipaddr('prefix') }}"
          - "Gateway: {{ item.addr | ipv6 | ipaddr('1') }}"
      with_items:
        - "{{ subinterfaces['red'] }}"
        - "{{ subinterfaces['purple'] }}"
        - "{{ subinterfaces['blue'] }}"

    - name: MAIN PARENT INTERFACE CONFIG
      cisco.ios.ios_interfaces:
      config:
        - name: "{{ interface }}"
          description: IPV6 ANSIBLE PLAYBOOK CONFIGURATION
          enabled: true

    - name: SUB INTERFACES CONFIG
      cisco.ios.ios_config:
        lines:
          - description {{ item.name }}
          - encapsulation dot1q {{ item.dot1q }}
          - ipv6 address {{ item.addr }}
          - ipv6 enable
          - ipv6 nd ra suppress all
        parents:
          - interface {{ interface }}.{{ item.dot1q }}
        match: strict
      with_items:
        - "{{ subinterfaces['red'] }}"
        - "{{ subinterfaces['purple'] }}"
        - "{{ subinterfaces['blue'] }}"

    - name: SHOW IPv6 INTERFACE BRIEF
      cisco.ios.ios_command:
        commands:
          - show ipv6 interface brief
      register: output

    - name: SAVE OUTPUT
      ansible.builtin.copy:
        content: "{{ output.stdout[0] }}"
        dest: "trace/ipv6_int_brief_{{ inventory_hostname }}.txt"
        mode: "0644"

    - name: REACHABILITY TEST
      cisco.ios.ios_ping:
        dest: "{{ item }}"
        afi: ipv6
      with_items:
        - "{{ subinterfaces['red'].addr | ipv6 | ipaddr('1') | ipaddr('address') }}"
        - "{{ subinterfaces['purple'].addr | ipv6 | ipaddr('1') | ipaddr('address') }}"
        - "{{ subinterfaces['blue'].addr | ipv6 | ipaddr('1') | ipaddr('address') }}"

Step 3: Examine your Ansible playbook.

The main purpose of this playbook is to illustrate variables formatting and calculations. From the host_vars/rtrXXX.yml file content, a set of VLAN identifiers is defined. Then, IPv6 subinterface addresses are calculated with a combination of:

  • The prefix stands for the network part
  • The VLAN id stands for the subnetwork part
  • The router id stands for the host part

Notice that we just have to change router and VLAN identifiers to get all the IPv6 addresses automatically calculated.

Now, il we consider the router_config_playbook.yml file content and its tasks, here is a brief description of the items used:

  • VARS ANALYSIS: Use the debug module to display the network's VLAN and topological addressing scheme.

  • MAIN PARENT INTERFACE CONFIG Use the ios_interfaces module to enable the parent network interface and set its description.

  • SUB INTERFACES CONFIG Use the ios_config module to send line-by-line configuration instructions for each VLAN sub-interface. This way of configuring network interfaces is useful when using instructions that are not provided by the Ansible libraries. The disadvantage here is that we lose idempotency and a warning will be sent each time we run the playbook. You can use the ansible-doc cisco.ios.ios_config command to see the details for the parents and match parameters used in this playbook.

  • SHOW IPv6 INTERFACE BRIEF Use the ios_command module to send the command show ipv6 interface brief. The command output is registered in an Ansible variable named output.

  • SAVE OUTPUT Use the copy module to save the content of the outpout variable into a file located in the trace directory on the Devnet VM.

  • REACHABILITY TEST Use the ios_ping module to send ICMPv6 requests to the network gateway of each subinterface VLAN.

Step 4: Run the Ansible playbook to configure IPv6 addressing on the virtual router.

Now you can run the Ansible playbook using the ansible-playbook command. The -vvv verbose option can be added to display the tasks being performed in the playbook.

:::warning Do not forget to change the rtr_id value in the host_vars/rtrXXX.yaml with your own out of band tap interface number! This is mandatory in order to avoid duplicate addresses on different virtual routers. :::

ansible-playbook router_config_playbook.yml --ask-vault-pass --extra-vars '@$HOME/lab14_passwd.yml'
Vault password:
PLAY [VLAN SUBINTERFACES CONFIGURATION] ***********

TASK [Gathering Facts] ****************************
ok: [rtr002]

TASK [VARS ANALYSIS] ******************************
ok: [rtr002] => (item={'name': 'RED VLAN SUBINTERFACE', 'dot1q': '100', 'addr': '2001:678:3fc:64::2/64'}) => {
    "msg": [
        "vlan: 100 --> address: 2001:678:3fc:64::XXX/64",
        "Network: 2001:678:3fc:64::/64",
        "Gateway: 2001:678:3fc:64::1/64"
    ]
}
ok: [rtr002] => (item={'name': 'PURPLE VLAN SUBINTERFACE', 'dot1q': '101', 'addr': '2001:678:3fc:65::2/64'}) => {
    "msg": [
        "vlan: 101 --> address: 2001:678:3fc:65::XXX/64",
        "Network: 2001:678:3fc:65::/64",
        "Gateway: 2001:678:3fc:65::1/64"
    ]
}
ok: [rtr002] => (item={'name': 'BLUE VLAN SUBINTERFACE', 'dot1q': '102', 'addr': '2001:678:3fc:66::2/64'}) => {
    "msg": [
        "vlan: 102 --> address: 2001:678:3fc:66::XXX/64",
        "Network: 2001:678:3fc:66::/64",
        "Gateway: 2001:678:3fc:66::1/64"
    ]
}

TASK [MAIN PARENT INTERFACE CONFIG] ***************
ok: [rtr002]

TASK [SUB INTERFACES CONFIG] **********************
changed: [rtr002] => (item={'name': 'RED VLAN SUBINTERFACE', 'dot1q': '100', 'addr': '2001:678:3fc:64::XXX/64'})
changed: [rtr002] => (item={'name': 'PURPLE VLAN SUBINTERFACE', 'dot1q': '101', 'addr': '2001:678:3fc:65::XXX/64'})
changed: [rtr002] => (item={'name': 'BLUE VLAN SUBINTERFACE', 'dot1q': '102', 'addr': '2001:678:3fc:66::XXX/64'})
[WARNING]: To ensure idempotency and correct diff the input configuration lines should be similar to how they appear if present in the running configuration on device

TASK [SHOW IPv6 INTERFACE BRIEF] ******************
ok: [rtr002]

TASK [SAVE OUTPUT] ********************************
ok: [rtr002]

TASK [REACHABILITY TEST] **************************
ok: [rtr002] => (item=2001:678:3fc:64::1)
ok: [rtr002] => (item=2001:678:3fc:65::1)
ok: [rtr002] => (item=2001:678:3fc:66::1)

PLAY RECAP ****************************************
rtr002     : ok=7    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Step 5: Verify the configuration trace file has been created.

You can view the trace file content with cat trace/ipv6_int_brief_Router.txt. You now have a trace of the virtual router interfaces and subinterfaces configuration.

cat trace/ipv6_int_brief_rtrXXX.txt 
GigabitEthernet1       [up/up]
    FE80::FAAD:CAFF:FEFE:XXX
    2001:678:3FC:1C:FAAD:CAFF:FEFE:XXX
GigabitEthernet2       [up/up]
    unassigned
GigabitEthernet2.100   [up/up]
    FE80::FAAD:CAFF:FEFE:YYY
    2001:678:3FC:64::XXX
GigabitEthernet2.101   [up/up]
    FE80::FAAD:CAFF:FEFE:YYY
    2001:678:3FC:65::XXX
GigabitEthernet2.102   [up/up]
    FE80::FAAD:CAFF:FEFE:YYY
    2001:678:3FC:66::XXX
GigabitEthernet3       [administratively down/down]
    unassigned
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment