Ansible 2.5 - New Network Modules

Ansible 2.5 just came out, and with it comes new network modules (and the network_cli and netconf connectivity methods). The new modules allow us to manage certain IOS configurations without always depending on the "ios_config" module, while the network_cli connectivity method means we don't always need to configure a "provider" for every network playbook. These new modules and connectivity methods allow networking configuration management to look and feel similar to our server management playbooks, which is great for cross-functional teams and reusability.

Ansible 2.5 Release Info:
New Networking Features in Ansible 2.5
List of All Network Modules in Ansible 2.5
Network Best Practices for Ansible 2.5

For a quick introduction, I'm going to take my previously discussed VLAN provisioning playbook and convert it to Ansible 2.5 syntax.

First, remember to upgrade to Ansible 2.5. If you have already have ansible installed, then just upgrade with:

apt-get update && apt-get install ansible

Our first major change is going to use "group_vars" to define connection settings for our network devices. By default, Ansible will read any variable in group_vars/all.yml, group_vars/<group_name> and host_vars/<host_name> when a playbook is executed. Since we are defining how to connect to all our Cisco IOS devices, I am going to put our connection variables in groups_vars/ios-switches.yml

ansible_connection: network_cli
ansible_network_os: ios
ansible_user: ciscoadmin
ansible_ssh_pass: cisco123

To use the network_cli connection, you must specify the "ansible_network_os". Also, please do not store your password in plain-text and instead use Ansible Vault, but to keep this example simple, we are using the password "cisco123".

Since our "ansible_connection" is defined in group_vars, we no longer need the "connection: local" parameter in our playbook.

Next, instead of using the "ios_config" module to create and name VLAN's, let's use the new ios_vlan module.

---
- hosts: ios-switches
  vars:
    vlan_id: 998
    vlan_name: Ansible_VLAN
    
tasks:
    - name: Provision VLAN
      ios_vlan:
        vlan_id: "{{ vlan_id }}"
        name: "{{ vlan_name }}"
        state: present

    - name: Show VLAN
      ios_command:
        commands: show vlan brief
      register: show_vlan

    - debug: var=show_vlan.stdout_lines

As you can see the ios_vlan module simplifies our VLAN provisioning process, since we can define the VLAN ID and the VLAN NAME in a single task. The "state" of the VLAN is not required to create a VLAN, but I included it to show how the new modules use declaritive statements to make creating/removing configuration easier. If we want to remove a VLAN, just change the "state" to absent. I also left in our "show vlan" task from last time, so we can verify our configuration change without logging into the switch manually.

Now to run the playbook:

root@ubuntu:/etc/ansible# ansible-playbook network_new-vlan.yml

PLAY [ios-switches] *************************************************************************************************************************************

TASK [Provision VLAN] ***********************************************************************************************************************************
changed: [10.170.200.2]

TASK [Show VLAN] ****************************************************************************************************************************************
ok: [10.170.200.2]

TASK [debug] ********************************************************************************************************************************************
ok: [10.170.200.2] => {
    "show_vlan.stdout_lines": [
        [
            "VLAN Name                             Status    Ports",
            "---- -------------------------------- --------- -------------------------------",
            "1    default                          active    Gi0/10, Gi0/11, Gi0/12",
            "10   FW_VLAN                          active    Gi0/3, Gi0/4, Gi0/5, Gi0/6, Gi0/7",
            "20   Data_VLAN                        active    Gi0/1, Gi0/2",
            "30   Voice_VLAN                       active    Gi0/1, Gi0/2, Gi0/3, Gi0/4, Gi0/5, Gi0/6, Gi0/7",
            "998  Ansible_VLAN                     active    ",
            "1002 fddi-default                     act/unsup ",
            "1003 token-ring-default               act/unsup ",
            "1004 fddinet-default                  act/unsup ",
            "1005 trnet-default                    act/unsup"
        ]
    ]
}

PLAY RECAP **********************************************************************************************************************************************
10.170.200.2                : ok=4    changed=1    unreachable=0    failed=0

Success!! While this is great for individual VLAN changes, the real power comes when you define all your environment VLAN's in group_var or host_var files, and looping through the "ios_vlan" task for every VLAN required. I'll save that for a future post!

You can find this playbook (including ansible.cfg and directory structure) on my github: https://github.com/dkuchenski/thenetworkstack-ansible/tree/master/vlan-provisioning-2.5