Ansible playbook to get all active L3 vlan interfaces from juniper switch

We will be using passwordless ssh access to the switch, so ssh-rsa key has to be configured on the target switch.
All we need to do here is to ssh to the switch, run the command: "show interfaces vlan terse  | match inet" and get vlan interface IDs from the output.
If the switch has vlan interfaces configured,  the output will look like this:

vlan.501upup inet 10.5.5.10/24
vlan.601upup inet 10.6.6.10/24

The following python regex will be used to get vlan interface numbers:

pulled_vlans = re.findall(r'vlan.(\d{3})', cli_output)

We need to write a simple custom Python ansible module that will be called from the playbook.

**TIP: To make a custom module available to Ansible, you can either specify the path to your custom module in an environment variable, ANSIBLE_LIBRARY; use the --module-path command-line option, or drop the modules in a ./library directory alongside your top-level playbooks.

I chose to follow the last option.

Here is module library/get_vlan_iface:

#!/usr/local/bin/python from jnpr.junos import Device import re import sys import json import os def main(): module = AnsibleModule( argument_spec=dict( host=dict(required=True), console=dict(required=False, default=None), user=dict(required=False, default=os.getenv('USER')), passwd=dict(required=False, default=None), port=dict(required=False, default=830)), supports_check_mode=True) m_args = module.params m_results = dict(changed=False) if m_args['console'] is None: try: from jnpr.junos import Device from jnpr.junos.version import VERSION if not float(re.match('\d+.\d+', VERSION).group()) >= 1.1: module.fail_json(msg='junos-eznc >= 1.1.x is required for this module') except ImportError: module.fail_json(msg='junos-eznc >= 1.1.x is required for this module') # ----------- # via NETCONF # ----------- dev = Device(m_args['host'], user=m_args['user'], passwd=m_args['passwd'], port=m_args['port']) try: dev.open() except Exception as err: msg = 'unable to connect to {0}: {1}'.format(m_args['host'], str(err)) module.fail_json(msg=msg) return else: pulled_vlan = [] vlan_interfaces = dev.cli('show interfaces vlan terse | match inet', warning=False) pulled_vlans = re.findall(r'vlan.(\d{3})', vlan_interfaces) pulled_vlans = map(int, pulled_vlans) m_results['vlan_iface'] = pulled_vlans dev.close() module.exit_json(**m_results) #--------------------------------------------------------------- # MAIN #--------------------------------------------------------------- from ansible.module_utils.basic import * main()

Next - we will create an inventory file network_inventory.corp:

[corp_switches] nyc-sw1.nets.net ipaddr=10.5.5.10


and a playbook file get_swi.yml:

--- - hosts: corp_switches connection: local gather_facts: no tasks: - name: running command get_vlan_iface: user='Username' host={{ inventory_hostname }} register: get_vlan_out - name: set var set_fact: vlan_iface: "{{ get_vlan_out.vlan_iface }}" - name: debug_vlans debug: var=get_vlan_out

To tset this module, we can use test-module script:

root@command-box] (master) # ./hacking/test-module -m library/get_vlan_iface -a "user='Username' host='10.5.5.10'" * including generated source, if any, saving to: /root/.ansible_module_generated * this may offset any line numbers in tracebacks/debuggers! *********************************** RAW OUTPUT {"changed": false, "vlan_iface": [501, 601]} *********************************** PARSED OUTPUT { "changed": false, "vlan_iface": [ 501, 601 ] }

And finally, we run the playbook:

root@command-box] (master) # ansible-playbook -i network-inventory.corp get_swi.yml PLAY [voip_switch] ************************************************************ TASK: [running command] ******************************************************* ok: [nyc-sw1.nets.net] TASK: [set var] *************************************************************** ok: [nyc-sw1.nets.net] TASK: [debug_vlans] *********************************************************** ok: [nyc-sw1.nets.net] => { "get_vlan_out": { "changed": false, "invocation": { "module_args": "user='Automate' host=port-corp-sw1.squarespace.net", "module_name": "get_vlan_iface" }, "vlan_iface": [ 501, 601 ] } } PLAY RECAP ******************************************************************** nyc-sw1.nets.net : ok=3 changed=0 unreachable=0 failed=0