├── doc ├── eve-topo.png ├── lldp_topo.png ├── vswitch_local.png └── vswitch_uplink.png ├── group_vars ├── all │ ├── vars │ └── vault.template └── lab │ └── vars ├── napalm_get_facts.yml ├── cisco_validate.yml ├── cisco_vlan_service.yml ├── backup_config.yml ├── roles ├── napalm_get_facts │ └── tasks │ │ └── main.yml ├── cisco_lldp_topo │ ├── tasks │ │ └── main.yml │ ├── templates │ │ └── lldp_topo.dot.j2 │ └── README.md ├── cisco_vlan_service │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── port_config.j2 │ │ └── interface_macros.j2 ├── cisco_device_provisioning │ ├── tasks │ │ └── main.yml │ ├── templates │ │ ├── provisioning_macros.j2 │ │ └── provisioning.j2 │ └── README.md ├── cisco_validate │ ├── tasks │ │ ├── main.yml │ │ └── interface_config.spec │ ├── templates │ │ └── validation_report.j2 │ └── README.md └── backup_config │ └── tasks │ └── main.yml ├── cisco_lldp_topo.yml ├── cisco_provisioning.yml ├── inventory ├── host_vars ├── s12-iol └── s11-iol ├── device_configs └── lab │ ├── mgmt-iol │ ├── s16-iol │ ├── s17-iol │ ├── s18-iol │ ├── s12-iol │ ├── s13-iol │ ├── s14-iol │ ├── s15-iol │ ├── s11-iol │ └── s01-iol ├── README.md └── ansible.cfg /doc/eve-topo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erikruiter2/ansible_lab/HEAD/doc/eve-topo.png -------------------------------------------------------------------------------- /doc/lldp_topo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erikruiter2/ansible_lab/HEAD/doc/lldp_topo.png -------------------------------------------------------------------------------- /doc/vswitch_local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erikruiter2/ansible_lab/HEAD/doc/vswitch_local.png -------------------------------------------------------------------------------- /doc/vswitch_uplink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erikruiter2/ansible_lab/HEAD/doc/vswitch_uplink.png -------------------------------------------------------------------------------- /group_vars/all/vars: -------------------------------------------------------------------------------- 1 | ansible_connection: network_cli 2 | ansible_network_os: ios 3 | ansible_user: ansible 4 | ansible_ssh_pass: "{{ vault_ansible_ssh_pass }}" 5 | 6 | 7 | -------------------------------------------------------------------------------- /group_vars/all/vault.template: -------------------------------------------------------------------------------- 1 | vault_ansible_ssh_pass: 2 | vault_cisco_console_pass: 3 | vault_cisco_enable_secret: 4 | vault_cisco_tacacs_key: 5 | -------------------------------------------------------------------------------- /napalm_get_facts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Gather napalm facts 3 | hosts: lab 4 | gather_facts: no 5 | 6 | roles: 7 | - { role: napalm_get_facts , filter: ['facts' ] } 8 | 9 | -------------------------------------------------------------------------------- /cisco_validate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Config validation for cisco devices 3 | hosts: lab 4 | connection: network_cli 5 | gather_facts: no 6 | 7 | roles: 8 | - cisco_validate 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /cisco_vlan_service.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: port config for cisco devices 3 | hosts: lab 4 | connection: network_cli 5 | gather_facts: no 6 | 7 | roles: 8 | - cisco_vlan_service 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /backup_config.yml: -------------------------------------------------------------------------------- 1 | - name: Backup configs 2 | hosts: all 3 | gather_facts: no 4 | 5 | vars: 6 | localpath: "/home/erikr/ansible_lab/device_configs" 7 | commit_message: "test" 8 | roles: 9 | - backup_config 10 | -------------------------------------------------------------------------------- /roles/napalm_get_facts/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: get LLDP information from device 2 | napalm_get_facts: 3 | hostname: '{{ inventory_hostname }}' 4 | username: '{{ ansible_user }}' 5 | dev_os: '{{ ansible_network_os }}' 6 | password: '{{ ansible_ssh_pass }}' 7 | filter: '{{ filter }}' 8 | register: result 9 | -------------------------------------------------------------------------------- /cisco_lldp_topo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Gather napalm facts 3 | hosts: lab 4 | gather_facts: no 5 | 6 | roles: 7 | - { role: napalm_get_facts , filter: ['facts', 'lldp_neighbors'] } 8 | 9 | - name: Generate LLDP topology graph 10 | hosts: localhost 11 | gather_facts: no 12 | 13 | roles: 14 | - cisco_lldp_topo 15 | 16 | -------------------------------------------------------------------------------- /cisco_provisioning.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Device and service provisioning for cisco devices 3 | hosts: lab 4 | connection: network_cli 5 | gather_facts: no 6 | 7 | roles: 8 | - { role: cisco_device_provisioning, tags: ['device'] } 9 | - { role: cisco_vlan_service, tags: ['service'] } 10 | - { role: cisco_validate, tags: ['validate'] } 11 | -------------------------------------------------------------------------------- /inventory: -------------------------------------------------------------------------------- 1 | [lab] 2 | s01-iol ansible_host=10.100.1.1 3 | s11-iol ansible_host=10.100.1.11 4 | s12-iol ansible_host=10.100.1.12 5 | s13-iol ansible_host=10.100.1.13 6 | s14-iol ansible_host=10.100.1.14 7 | s15-iol ansible_host=10.100.1.15 8 | s16-iol ansible_host=10.100.1.16 9 | s17-iol ansible_host=10.100.1.17 10 | s18-iol ansible_host=10.100.1.18 11 | mgmt-iol ansible_host=10.100.1.100 12 | -------------------------------------------------------------------------------- /roles/cisco_lldp_topo/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: generate .dot data 2 | set_fact: 3 | lldp_topo: "{{ lookup('template', 'lldp_topo.dot.j2') }}" 4 | delegate_to: localhost 5 | run_once: True 6 | 7 | - name: generate lldp_topo.png 8 | command: /usr/bin/dot -Tpng -o lldp_topo.png 9 | args: 10 | stdin: "{{ lldp_topo }}" 11 | delegate_to: localhost 12 | run_once: True 13 | -------------------------------------------------------------------------------- /roles/cisco_vlan_service/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: generate CLI output 3 | set_fact: 4 | port_config: "{{ lookup('template', 'port_config.j2') }}" 5 | delegate_to: 127.0.0.1 6 | - debug: var=port_config 7 | 8 | - name: Pushing config ... please wait 9 | ios_config: 10 | src: port_config.j2 11 | ignore_errors: yes 12 | register: OUTPUT 13 | 14 | - debug: var=OUTPUT 15 | 16 | -------------------------------------------------------------------------------- /roles/cisco_device_provisioning/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: generate CLI output 3 | set_fact: 4 | prov_config: "{{ lookup('template', 'provisioning.j2') }}" 5 | delegate_to: localhost 6 | - debug: var=prov_config 7 | 8 | - name: Pushing config ... please wait 9 | ios_config: 10 | src: provisioning.j2 11 | ignore_errors: yes 12 | register: OUTPUT 13 | 14 | - debug: var=OUTPUT 15 | 16 | -------------------------------------------------------------------------------- /roles/cisco_validate/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: get config info from device 3 | napalm_get_facts: 4 | hostname: '{{ inventory_hostname }}' 5 | username: '{{ ansible_user }}' 6 | dev_os: '{{ ansible_network_os }}' 7 | password: '{{ ansible_ssh_pass }}' 8 | filter: ['config','interfaces'] 9 | register: result 10 | 11 | - name: parse received config info 12 | set_fact: 13 | spec_result: "{{ result.ansible_facts.napalm_config.running | parse_cli('roles/cisco_validate/tasks/interface_config.spec') }}" 14 | 15 | - name: Write validation report to file 16 | template: 17 | src: validation_report.j2 18 | dest: "{{ inventory_hostname }}_validation_report.txt" 19 | 20 | 21 | -------------------------------------------------------------------------------- /roles/backup_config/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Role requires localpath to be defined as storage location of the config files 3 | - name: create group directories 4 | file: 5 | path: "{{ localpath }}/{{ item }}" 6 | state: directory 7 | with_items: "{{ group_names }}" 8 | 9 | - name: get config from device 10 | napalm_get_facts: 11 | hostname: '{{ inventory_hostname }}' 12 | username: '{{ ansible_user }}' 13 | dev_os: '{{ ansible_network_os }}' 14 | password: '{{ ansible_ssh_pass }}' 15 | filter: ['config'] 16 | register: result 17 | 18 | - name: Write config to file 19 | copy: 20 | content: "{{ result.ansible_facts.napalm_config.running }}" 21 | dest: "{{ localpath }}/{{ item }}/{{ inventory_hostname }}" 22 | with_items: "{{ group_names }}" 23 | 24 | - name: add changes to git repo 25 | shell: "git add {{ localpath }}/{{ item }}/*" 26 | with_items: "{{ group_names }}" 27 | delegate_to: 127.0.0.1 28 | run_once: True 29 | 30 | 31 | - name: commit changes to git repo 32 | shell: "git commit -m {{ commit_message }}" 33 | delegate_to: 127.0.0.1 34 | run_once: True 35 | -------------------------------------------------------------------------------- /host_vars/s12-iol: -------------------------------------------------------------------------------- 1 | poe_supported: False 2 | 3 | interfaces: 4 | # Ethernet0/0: 5 | # portprofile: lab_uplink_port 6 | # Ethernet0/1: 7 | # portprofile: lab_uplink_port 8 | Ethernet0/2: 9 | portprofile: cctv 10 | Ethernet0/3: 11 | adminstate: enabled 12 | associated_asset: '' 13 | vlan: 411 14 | portmode: access 15 | poe: false 16 | Ethernet1/0: 17 | portprofile: office 18 | Ethernet1/1: 19 | portprofile: office 20 | Ethernet1/2: 21 | portprofile: office 22 | Ethernet1/3: 23 | description: AP ground floor 24 | portprofile: office 25 | Ethernet2/0: 26 | description: AP first floor 27 | portprofile: wifi_accesspoint 28 | Ethernet2/1: 29 | description: Office file server 30 | portprofile: office 31 | poe: False 32 | Ethernet2/2: 33 | description: 34 | portmode: trunk 35 | vlan: 10,20 36 | nativevlan: 10 37 | Ethernet2/3: 38 | portprofile: disabled 39 | Ethernet3/0: 40 | portprofile: disabled 41 | Ethernet3/1: 42 | portprofile: disabled 43 | Ethernet3/2: 44 | portprofile: disabled 45 | # Ethernet3/3: 46 | # portprofile: lab_switch_mgmt_vlan_10 47 | # customstatements: 48 | # - no spanning-tree bpduguard enable 49 | -------------------------------------------------------------------------------- /roles/cisco_lldp_topo/templates/lldp_topo.dot.j2: -------------------------------------------------------------------------------- 1 | digraph G { 2 | splines=true; 3 | overlap=scalexy; 4 | 5 | edge [ 6 | arrowhead="none" 7 | ]; 8 | 9 | node [style="rounded,filled,bold", shape=box, width=1.3, fontname="Arial"]; 10 | edge [fontsize=10]; 11 | {% set already_done = [] %} 12 | {% for host in hostvars %} 13 | {% if 'napalm_lldp_neighbors' in hostvars[host]['ansible_facts'] %} 14 | {% set fqdn = hostvars[host]['ansible_facts']['napalm_fqdn'] %} 15 | {% set lldp_data = hostvars[host]['ansible_facts']['napalm_lldp_neighbors'] %} 16 | {% for interface in lldp_data %} 17 | {% if { lldp_data[interface][0]['hostname'] : lldp_data[interface][0]['port'] | lower|regex_replace('(?P^\\D\\D)\\D+(?P\\d.+)','\\g\\g') } not in already_done %} 18 | "{{ fqdn }}" -> "{{ lldp_data[interface][0]['hostname'] }}" [minlen=2 headlabel="{{ lldp_data[interface][0]['port'] }}" taillabel="{{ interface | regex_replace('(?P^\\D\\D)\\D+(?P\\d.+)','\\g\\g') }}"]; 19 | {% endif %} 20 | {{ already_done.append( { fqdn : interface | lower|regex_replace('(?P^\\D\\D)\\D+(?P\\d.+)','\\g\\g') }) }} 21 | {% endfor %} 22 | {% endif %} 23 | {% endfor %} 24 | } 25 | -------------------------------------------------------------------------------- /roles/cisco_validate/tasks/interface_config.spec: -------------------------------------------------------------------------------- 1 | --- 2 | vars: 3 | interface: 4 | name: "{{ item[0].match[0] | trim }}" 5 | description: "{{ item[1].match[0] | trim }}" 6 | vlan: "{% if item[5].match[0] == 'access'%}{{ item[2].match[0] | trim }}{% elif item[5].match[0] == 'trunk' %}{{ item[9].match[0]}}{%endif%}" 7 | voicevlan: "{{ item[3].match[0] | trim }}" 8 | nativevlan: "{{ item[4].match[0] | trim }}" 9 | portmode: "{{ item[5].match[0] | trim }}" 10 | adminstate: "{% if item[6] == None %}enabled{%else%}disabled{%endif%}" 11 | poe: "{% if item[7] == None %}{{ true }}{%else%}{{ false }}{%endif%}" 12 | cdp: "{% if item[8] == None %}{{ true }}{%else%}{{ false }}{%endif%}" 13 | trunkallowedvlan: "{% if item[9].match[0] is iterable and item[9].match[0] is not string%}1{{ item[9].match[0] |join(',')}}{%else%}2{{item[9].match[0]}}{%endif%}" 14 | keys: 15 | interfaces: 16 | value: "{{ interface }}" 17 | start_block: "^interface .+$" 18 | end_block: "^!$" 19 | items: 20 | - "interface (.+)" 21 | - " description (.+)" 22 | - " switchport access vlan (.+)" 23 | - " switchport voice vlan (.+)" 24 | - " switchport trunk native vlan (.+)" 25 | - " switchport mode (.+)" 26 | - " (?Pshutdown|no shutdown)" 27 | - " (?Ppower inline auto|power inline never)" 28 | - " (?Pno cdp enable|cdp enable)" 29 | - " switchport trunk allowed vlan (.+)" -------------------------------------------------------------------------------- /roles/cisco_vlan_service/templates/port_config.j2: -------------------------------------------------------------------------------- 1 | {% import 'interface_macros.j2' as int %} 2 | 3 | {# Generate VLANs known on the switch #} 4 | 5 | {% for vlan in vlans %} 6 | {% for name, id in vlan.items() %} 7 | vlan {{ id }} 8 | name {{ name }} 9 | {% endfor %} 10 | {% endfor %} 11 | 12 | {# Generate per interface configuration making use of either port profiles or variables as stated in the host_vars file #} 13 | {% set defaults = { "description": "", 14 | "vlan": "1", 15 | "voicevlan": None, 16 | "nativevlan": "1", 17 | "portmode": 'access', 18 | "adminstate": 'disabled', 19 | "poe": False, 20 | "cdp": True } %} 21 | {% for port in interfaces %} 22 | int {{ port }} 23 | {% set interface = interfaces[port] %} 24 | {% if 'portprofile' in interface %} 25 | {% if interfaces[port]['portprofile'] in portprofiles|map(attribute="name") %} 26 | {% set portprofile = portprofiles | selectattr('name', 'equalto', interfaces[port]['portprofile'] ) | list %} 27 | {% for p in defaults.keys() %} 28 | {% if p in interface %}{{ int.set_parameter(p, interface) }}{% else %} 29 | {{ int.set_parameter(p, portprofile[0]) }}{% endif %} 30 | {% endfor %} 31 | {% endif %} 32 | {% else %} 33 | {% for p in defaults.keys() %} 34 | {% if p in interface %}{{ int.set_parameter(p, interface) }}{% else %} 35 | {{ int.set_parameter(p, {p: defaults[p]}) }}{% endif %} 36 | {% endfor %} 37 | {% endif %} 38 | exit 39 | {% endfor %} 40 | 41 | -------------------------------------------------------------------------------- /roles/cisco_device_provisioning/templates/provisioning_macros.j2: -------------------------------------------------------------------------------- 1 | {% macro set_snmp(snmp) %} 2 | {% for server in snmp %} 3 | {% set access = 'RO' %} 4 | {% if 'access' in server.keys() %} 5 | {% if server['access'] == 'readwrite' %}{% set access = 'RW' %} {% endif %} 6 | {% endif %} 7 | snmp-server community {{ server['community'] }} {{ access }} 8 | snmp-server host {{ server['server'] }} version {{ server['version'] }} {{ server['community'] }} 9 | {% endfor %} 10 | {% endmacro %} 11 | 12 | {% macro set_tacacs(tacacs) %} 13 | {% for server in tacacs %} 14 | tacacs-server host {{ server['server'] }} timeout 1 15 | tacacs-server key 0 {{ server['key'] }} 16 | {% endfor %} 17 | tacacs-server directed-request 18 | {% endmacro %} 19 | 20 | {% macro set_syslog(syslog) %} 21 | {% for server in syslog %} 22 | logging host {{ server['server'] }} 23 | {% endfor %} 24 | {% endmacro %} 25 | 26 | {% macro set_ntp(ntp) %} 27 | {% for server in ntp %} 28 | ntp server {{ server['server'] }} 29 | {% endfor %} 30 | {% endmacro %} 31 | 32 | {% macro set_dnsservers(dnsservers) %} 33 | ip domain lookup 34 | {% for server in dnsservers %} 35 | ip name-server {{ server }} 36 | {% endfor %} 37 | {% endmacro %} 38 | 39 | {% macro set_mgmt_svi(sw_mgmt_svi) %} 40 | interface vlan{{ sw_mgmt_svi[0]['vlan'] }} 41 | description management interface 42 | ip address {{ sw_mgmt_svi[0]['ip'] }} {{ sw_mgmt_svi[0]['netmask'] }} 43 | no shut 44 | ip default-gateway {{ sw_mgmt_svi[0]['default_gw'] }} 45 | ntp source vlan {{ sw_mgmt_svi[0]['vlan'] }} 46 | logging source-interface vlan{{ sw_mgmt_svi[0]['vlan'] }} 47 | snmp-server source-interface traps vlan{{ sw_mgmt_svi[0]['vlan'] }} 48 | {% endmacro %} 49 | 50 | {% macro set_users(users) %} 51 | {% for user in users %} 52 | username {{ user['name'] }} privilege 15 secret 0 {{ user['password'] }} 53 | {% endfor %} 54 | {% endmacro %} 55 | -------------------------------------------------------------------------------- /host_vars/s11-iol: -------------------------------------------------------------------------------- 1 | interfaces: 2 | Ethernet0/0: 3 | adminstate: enabled 4 | associated_asset: '' 5 | description: '' 6 | poe: false 7 | portprofile: lab_uplink_port 8 | Ethernet0/1: 9 | adminstate: enabled 10 | associated_asset: '' 11 | description: '' 12 | poe: false 13 | portprofile: lab_uplink_port 14 | Ethernet0/2: 15 | adminstate: enabled 16 | associated_asset: '' 17 | description: '' 18 | poe: false 19 | portprofile: lab_cctv_vlan_100 20 | Ethernet0/3: 21 | adminstate: enabled 22 | associated_asset: '' 23 | description: '' 24 | poe: false 25 | portprofile: lab_cctv_vlan_100 26 | Ethernet1/0: 27 | adminstate: enabled 28 | associated_asset: '' 29 | description: '' 30 | poe: false 31 | portprofile: lab_cctv_vlan_100 32 | Ethernet1/1: 33 | adminstate: enabled 34 | associated_asset: '' 35 | description: '' 36 | poe: false 37 | portprofile: lab_cctv_vlan_100 38 | Ethernet1/2: 39 | adminstate: enabled 40 | associated_asset: '' 41 | description: '' 42 | poe: false 43 | portprofile: lab_bms_vlan_101 44 | Ethernet1/3: 45 | adminstate: enabled 46 | associated_asset: '' 47 | description: '' 48 | poe: false 49 | portprofile: lab_bms_vlan_101 50 | Ethernet2/0: 51 | adminstate: enabled 52 | associated_asset: '' 53 | description: '' 54 | poe: false 55 | portprofile: lab_bms_vlan_101 56 | Ethernet2/1: 57 | adminstate: enabled 58 | associated_asset: '' 59 | description: '' 60 | poe: false 61 | portprofile: lab_bms_vlan_101 62 | Ethernet2/2: 63 | adminstate: disabled 64 | associated_asset: '' 65 | description: '' 66 | poe: false 67 | portprofile: disabled 68 | Ethernet2/3: 69 | adminstate: disabled 70 | associated_asset: '' 71 | description: '' 72 | poe: false 73 | portprofile: disabled 74 | Ethernet3/0: 75 | adminstate: disabled 76 | associated_asset: '' 77 | description: '' 78 | poe: false 79 | portprofile: disabled 80 | Ethernet3/1: 81 | adminstate: disabled 82 | associated_asset: '' 83 | description: '' 84 | poe: false 85 | portprofile: disabled 86 | Ethernet3/2: 87 | adminstate: disabled 88 | associated_asset: '' 89 | description: '' 90 | poe: false 91 | portprofile: disabled 92 | Ethernet3/3: 93 | adminstate: enabled 94 | associated_asset: '' 95 | description: '' 96 | poe: false 97 | portprofile: lab_switch_mgmt_vlan_10 98 | -------------------------------------------------------------------------------- /group_vars/lab/vars: -------------------------------------------------------------------------------- 1 | 2 | # Per group device provisioning variables: 3 | 4 | syslog: 5 | - server: 192.168.1.1 6 | 7 | snmp: 8 | - server: 192.168.1.1 9 | community: public 10 | version: 2c 11 | access: readonly 12 | - server: 192.168.1.2 13 | community: test123 14 | version: 2c 15 | access: readwrite 16 | 17 | dnsdomain: inxn.net 18 | 19 | dnsservers: 20 | - 8.8.8.8 21 | - 4.4.4.4 22 | 23 | ntp: 24 | - server: 192.168.1.1 25 | 26 | sw_mgmt_svi: 27 | - vlan: 10 28 | ip: "{{ ansible_host }}" 29 | netmask: 255.255.255.0 30 | default_gw: 10.1.100.1 31 | 32 | users: 33 | - name: ansible 34 | password: "{{ ansible_ssh_pass }}" 35 | - name: netuser 36 | password: bladiebla 37 | 38 | 39 | console_password: "{{ vault_cisco_console_pass }}" 40 | enable_secret: "{{ vault_cisco_enable_secret }}" 41 | 42 | tacacs: 43 | - server: 192.168.1.1 44 | key: "{{ vault_cisco_tacacs_key }}" 45 | - server: 192.168.1.2 46 | key: "{{ vault_cisco_tacacs_key }}" 47 | 48 | # Per group VLAN service provisioning 49 | 50 | vlans: 51 | - cctv: 411 52 | - ipphone: 39 53 | - office: 15 54 | - wifi: 999 55 | - wifi_mgmt: 998 56 | - sw_mgmt: 10 57 | 58 | portprofiles: 59 | - name: lab_switch_mgmt_vlan_10 60 | adminstate: enabled 61 | subnet: 10.1.0.0/24 62 | portmode: access 63 | vlan: 10 64 | poe: False 65 | cdp: True 66 | - name: cctv 67 | adminstate: enabled 68 | subnet: 10.1.1.0/24 69 | portmode: access 70 | vlan: 411 71 | portsecurity: sticky 72 | poe: True 73 | cdp: False 74 | - name: office 75 | adminstate: enabled 76 | description: port configuration for Office desktops and phones 77 | subnet: 192.168.1.0/24 78 | portmode: access 79 | vlan: 15 80 | voicevlan: 39 81 | poe: True 82 | cdp: False 83 | portsecurity: none 84 | - name: wifi_accesspoint 85 | adminstate: enabled 86 | description: port configuration for WIFI accesspoints 87 | subnet: 192.168.99.0/24 88 | portmode: trunk 89 | vlan: 998,999 90 | nativevlan: 998 91 | poe: True 92 | cdp: False 93 | - name: lab_uplink_port 94 | adminstate: enabled 95 | description: Uplink port 96 | subnet: 0.0.0.0/0 97 | portmode: trunk 98 | vlan: all 99 | poe: False 100 | cdp: True 101 | - name: disabled 102 | portmode: access 103 | vlan: 2 104 | adminstate: disabled 105 | description: disabled 106 | portsecurity: none -------------------------------------------------------------------------------- /device_configs/lab/mgmt-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 1859 bytes 4 | ! 5 | ! Last configuration change at 21:50:09 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname mgmt-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | ! 33 | ip cef 34 | ! 35 | ! 36 | no ip domain-lookup 37 | ip domain-name inxn.net 38 | no ipv6 cef 39 | ipv6 multicast rpf use-bgp 40 | ! 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | spanning-tree mode pvst 48 | spanning-tree extend system-id 49 | ! 50 | ! 51 | ! 52 | ! 53 | vlan internal allocation policy ascending 54 | lldp run 55 | ! 56 | ip ssh version 2 57 | ! 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | interface Ethernet0/0 67 | switchport access vlan 10 68 | switchport mode access 69 | ! 70 | interface Ethernet0/1 71 | switchport access vlan 10 72 | switchport mode access 73 | ! 74 | interface Ethernet0/2 75 | switchport access vlan 10 76 | switchport mode access 77 | ! 78 | interface Ethernet0/3 79 | switchport access vlan 10 80 | switchport mode access 81 | ! 82 | interface Ethernet1/0 83 | switchport access vlan 10 84 | switchport mode access 85 | ! 86 | interface Ethernet1/1 87 | switchport access vlan 10 88 | switchport mode access 89 | ! 90 | interface Ethernet1/2 91 | switchport access vlan 10 92 | switchport mode access 93 | ! 94 | interface Ethernet1/3 95 | switchport access vlan 10 96 | switchport mode access 97 | ! 98 | interface Ethernet2/0 99 | shutdown 100 | ! 101 | interface Ethernet2/1 102 | shutdown 103 | ! 104 | interface Ethernet2/2 105 | shutdown 106 | ! 107 | interface Ethernet2/3 108 | shutdown 109 | ! 110 | interface Ethernet3/0 111 | shutdown 112 | ! 113 | interface Ethernet3/1 114 | shutdown 115 | ! 116 | interface Ethernet3/2 117 | switchport access vlan 10 118 | switchport mode access 119 | ! 120 | interface Ethernet3/3 121 | switchport access vlan 10 122 | switchport mode access 123 | ! 124 | interface Vlan10 125 | ip address 10.100.1.100 255.255.255.0 126 | ! 127 | ! 128 | no ip http server 129 | ! 130 | ! 131 | ! 132 | ! 133 | ! 134 | ! 135 | ! 136 | control-plane 137 | ! 138 | ! 139 | line con 0 140 | logging synchronous 141 | line aux 0 142 | line vty 1 4 143 | transport input ssh 144 | ! 145 | end -------------------------------------------------------------------------------- /device_configs/lab/s16-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 2062 bytes 4 | ! 5 | ! Last configuration change at 21:46:54 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname s16-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | no ip routing 33 | ! 34 | no ip cef 35 | ! 36 | ! 37 | no ip domain-lookup 38 | ip domain-name inxn.net 39 | no ipv6 cef 40 | ipv6 multicast rpf use-bgp 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | spanning-tree mode pvst 49 | spanning-tree extend system-id 50 | ! 51 | ! 52 | ! 53 | ! 54 | vlan internal allocation policy ascending 55 | lldp run 56 | ! 57 | ip ssh version 2 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | ! 67 | interface Port-channel1 68 | switchport 69 | switchport trunk encapsulation dot1q 70 | switchport trunk allowed vlan 1-9,11-4094 71 | switchport mode trunk 72 | ! 73 | interface Ethernet0/0 74 | switchport trunk encapsulation dot1q 75 | switchport trunk allowed vlan 1-9,11-4094 76 | switchport mode trunk 77 | channel-group 1 mode active 78 | ! 79 | interface Ethernet0/1 80 | switchport trunk encapsulation dot1q 81 | switchport trunk allowed vlan 1-9,11-4094 82 | switchport mode trunk 83 | channel-group 1 mode active 84 | ! 85 | interface Ethernet0/2 86 | shutdown 87 | duplex auto 88 | ! 89 | interface Ethernet0/3 90 | shutdown 91 | duplex auto 92 | ! 93 | interface Ethernet1/0 94 | shutdown 95 | duplex auto 96 | ! 97 | interface Ethernet1/1 98 | shutdown 99 | duplex auto 100 | ! 101 | interface Ethernet1/2 102 | shutdown 103 | duplex auto 104 | ! 105 | interface Ethernet1/3 106 | shutdown 107 | duplex auto 108 | ! 109 | interface Ethernet2/0 110 | shutdown 111 | duplex auto 112 | ! 113 | interface Ethernet2/1 114 | shutdown 115 | duplex auto 116 | ! 117 | interface Ethernet2/2 118 | shutdown 119 | duplex auto 120 | ! 121 | interface Ethernet2/3 122 | shutdown 123 | duplex auto 124 | ! 125 | interface Ethernet3/0 126 | shutdown 127 | duplex auto 128 | ! 129 | interface Ethernet3/1 130 | shutdown 131 | duplex auto 132 | ! 133 | interface Ethernet3/2 134 | shutdown 135 | duplex auto 136 | ! 137 | interface Ethernet3/3 138 | switchport access vlan 10 139 | switchport mode access 140 | ! 141 | interface Vlan10 142 | ip address 10.100.1.16 255.255.255.0 143 | ! 144 | ! 145 | no ip http server 146 | ! 147 | ! 148 | ! 149 | ! 150 | ! 151 | ! 152 | ! 153 | control-plane 154 | ! 155 | ! 156 | line con 0 157 | logging synchronous 158 | line aux 0 159 | line vty 1 4 160 | transport input ssh 161 | ! 162 | end -------------------------------------------------------------------------------- /device_configs/lab/s17-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 2062 bytes 4 | ! 5 | ! Last configuration change at 21:47:23 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname s17-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | no ip routing 33 | ! 34 | no ip cef 35 | ! 36 | ! 37 | no ip domain-lookup 38 | ip domain-name inxn.net 39 | no ipv6 cef 40 | ipv6 multicast rpf use-bgp 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | spanning-tree mode pvst 49 | spanning-tree extend system-id 50 | ! 51 | ! 52 | ! 53 | ! 54 | vlan internal allocation policy ascending 55 | lldp run 56 | ! 57 | ip ssh version 2 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | ! 67 | interface Port-channel1 68 | switchport 69 | switchport trunk encapsulation dot1q 70 | switchport trunk allowed vlan 1-9,11-4094 71 | switchport mode trunk 72 | ! 73 | interface Ethernet0/0 74 | switchport trunk encapsulation dot1q 75 | switchport trunk allowed vlan 1-9,11-4094 76 | switchport mode trunk 77 | channel-group 1 mode active 78 | ! 79 | interface Ethernet0/1 80 | switchport trunk encapsulation dot1q 81 | switchport trunk allowed vlan 1-9,11-4094 82 | switchport mode trunk 83 | channel-group 1 mode active 84 | ! 85 | interface Ethernet0/2 86 | shutdown 87 | duplex auto 88 | ! 89 | interface Ethernet0/3 90 | shutdown 91 | duplex auto 92 | ! 93 | interface Ethernet1/0 94 | shutdown 95 | duplex auto 96 | ! 97 | interface Ethernet1/1 98 | shutdown 99 | duplex auto 100 | ! 101 | interface Ethernet1/2 102 | shutdown 103 | duplex auto 104 | ! 105 | interface Ethernet1/3 106 | shutdown 107 | duplex auto 108 | ! 109 | interface Ethernet2/0 110 | shutdown 111 | duplex auto 112 | ! 113 | interface Ethernet2/1 114 | shutdown 115 | duplex auto 116 | ! 117 | interface Ethernet2/2 118 | shutdown 119 | duplex auto 120 | ! 121 | interface Ethernet2/3 122 | shutdown 123 | duplex auto 124 | ! 125 | interface Ethernet3/0 126 | shutdown 127 | duplex auto 128 | ! 129 | interface Ethernet3/1 130 | shutdown 131 | duplex auto 132 | ! 133 | interface Ethernet3/2 134 | shutdown 135 | duplex auto 136 | ! 137 | interface Ethernet3/3 138 | switchport access vlan 10 139 | switchport mode access 140 | ! 141 | interface Vlan10 142 | ip address 10.100.1.17 255.255.255.0 143 | ! 144 | ! 145 | no ip http server 146 | ! 147 | ! 148 | ! 149 | ! 150 | ! 151 | ! 152 | ! 153 | control-plane 154 | ! 155 | ! 156 | line con 0 157 | logging synchronous 158 | line aux 0 159 | line vty 1 4 160 | transport input ssh 161 | ! 162 | end -------------------------------------------------------------------------------- /device_configs/lab/s18-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 2062 bytes 4 | ! 5 | ! Last configuration change at 21:47:46 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname s18-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | no ip routing 33 | ! 34 | no ip cef 35 | ! 36 | ! 37 | no ip domain-lookup 38 | ip domain-name inxn.net 39 | no ipv6 cef 40 | ipv6 multicast rpf use-bgp 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | spanning-tree mode pvst 49 | spanning-tree extend system-id 50 | ! 51 | ! 52 | ! 53 | ! 54 | vlan internal allocation policy ascending 55 | lldp run 56 | ! 57 | ip ssh version 2 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | ! 67 | interface Port-channel1 68 | switchport 69 | switchport trunk encapsulation dot1q 70 | switchport trunk allowed vlan 1-9,11-4094 71 | switchport mode trunk 72 | ! 73 | interface Ethernet0/0 74 | switchport trunk encapsulation dot1q 75 | switchport trunk allowed vlan 1-9,11-4094 76 | switchport mode trunk 77 | channel-group 1 mode active 78 | ! 79 | interface Ethernet0/1 80 | switchport trunk encapsulation dot1q 81 | switchport trunk allowed vlan 1-9,11-4094 82 | switchport mode trunk 83 | channel-group 1 mode active 84 | ! 85 | interface Ethernet0/2 86 | shutdown 87 | duplex auto 88 | ! 89 | interface Ethernet0/3 90 | shutdown 91 | duplex auto 92 | ! 93 | interface Ethernet1/0 94 | shutdown 95 | duplex auto 96 | ! 97 | interface Ethernet1/1 98 | shutdown 99 | duplex auto 100 | ! 101 | interface Ethernet1/2 102 | shutdown 103 | duplex auto 104 | ! 105 | interface Ethernet1/3 106 | shutdown 107 | duplex auto 108 | ! 109 | interface Ethernet2/0 110 | shutdown 111 | duplex auto 112 | ! 113 | interface Ethernet2/1 114 | shutdown 115 | duplex auto 116 | ! 117 | interface Ethernet2/2 118 | shutdown 119 | duplex auto 120 | ! 121 | interface Ethernet2/3 122 | shutdown 123 | duplex auto 124 | ! 125 | interface Ethernet3/0 126 | shutdown 127 | duplex auto 128 | ! 129 | interface Ethernet3/1 130 | shutdown 131 | duplex auto 132 | ! 133 | interface Ethernet3/2 134 | shutdown 135 | duplex auto 136 | ! 137 | interface Ethernet3/3 138 | switchport access vlan 10 139 | switchport mode access 140 | ! 141 | interface Vlan10 142 | ip address 10.100.1.18 255.255.255.0 143 | ! 144 | ! 145 | no ip http server 146 | ! 147 | ! 148 | ! 149 | ! 150 | ! 151 | ! 152 | ! 153 | control-plane 154 | ! 155 | ! 156 | line con 0 157 | logging synchronous 158 | line aux 0 159 | line vty 1 4 160 | transport input ssh 161 | ! 162 | end -------------------------------------------------------------------------------- /device_configs/lab/s12-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 2106 bytes 4 | ! 5 | ! Last configuration change at 21:38:38 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname s12-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | no ip routing 33 | ! 34 | no ip cef 35 | ! 36 | ! 37 | no ip domain-lookup 38 | ip domain-name inxn.net 39 | no ipv6 cef 40 | ipv6 multicast rpf use-bgp 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | spanning-tree mode pvst 49 | spanning-tree extend system-id 50 | ! 51 | ! 52 | ! 53 | ! 54 | vlan internal allocation policy ascending 55 | lldp run 56 | ! 57 | ip ssh version 2 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | ! 67 | interface Port-channel1 68 | switchport 69 | switchport trunk encapsulation dot1q 70 | switchport trunk allowed vlan 1-9,11-4094 71 | switchport mode trunk 72 | ! 73 | interface Ethernet0/0 74 | switchport trunk encapsulation dot1q 75 | switchport trunk allowed vlan 1-9,11-4094 76 | switchport mode trunk 77 | channel-group 1 mode active 78 | ! 79 | interface Ethernet0/1 80 | switchport trunk encapsulation dot1q 81 | switchport trunk allowed vlan 1-9,11-4094 82 | switchport mode trunk 83 | channel-group 1 mode active 84 | ! 85 | interface Ethernet0/2 86 | shutdown 87 | duplex auto 88 | ! 89 | interface Ethernet0/3 90 | shutdown 91 | duplex auto 92 | ! 93 | interface Ethernet1/0 94 | shutdown 95 | duplex auto 96 | ! 97 | interface Ethernet1/1 98 | shutdown 99 | duplex auto 100 | ! 101 | interface Ethernet1/2 102 | shutdown 103 | duplex auto 104 | ! 105 | interface Ethernet1/3 106 | shutdown 107 | duplex auto 108 | ! 109 | interface Ethernet2/0 110 | shutdown 111 | duplex auto 112 | ! 113 | interface Ethernet2/1 114 | shutdown 115 | duplex auto 116 | ! 117 | interface Ethernet2/2 118 | shutdown 119 | duplex auto 120 | ! 121 | interface Ethernet2/3 122 | shutdown 123 | duplex auto 124 | ! 125 | interface Ethernet3/0 126 | shutdown 127 | duplex auto 128 | ! 129 | interface Ethernet3/1 130 | shutdown 131 | duplex auto 132 | ! 133 | interface Ethernet3/2 134 | shutdown 135 | duplex auto 136 | ! 137 | interface Ethernet3/3 138 | switchport access vlan 10 139 | switchport mode access 140 | ! 141 | interface Vlan10 142 | ip address 10.100.1.12 255.255.255.0 143 | no ip route-cache 144 | ! 145 | ! 146 | no ip http server 147 | ! 148 | ! 149 | ! 150 | ! 151 | snmp-server location PAR 152 | ! 153 | ! 154 | ! 155 | control-plane 156 | ! 157 | ! 158 | line con 0 159 | logging synchronous 160 | line aux 0 161 | line vty 1 4 162 | transport input ssh 163 | ! 164 | end -------------------------------------------------------------------------------- /device_configs/lab/s13-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 2106 bytes 4 | ! 5 | ! Last configuration change at 21:40:44 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname s13-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | no ip routing 33 | ! 34 | no ip cef 35 | ! 36 | ! 37 | no ip domain-lookup 38 | ip domain-name inxn.net 39 | no ipv6 cef 40 | ipv6 multicast rpf use-bgp 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | spanning-tree mode pvst 49 | spanning-tree extend system-id 50 | ! 51 | ! 52 | ! 53 | ! 54 | vlan internal allocation policy ascending 55 | lldp run 56 | ! 57 | ip ssh version 2 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | ! 67 | interface Port-channel1 68 | switchport 69 | switchport trunk encapsulation dot1q 70 | switchport trunk allowed vlan 1-9,11-4094 71 | switchport mode trunk 72 | ! 73 | interface Ethernet0/0 74 | switchport trunk encapsulation dot1q 75 | switchport trunk allowed vlan 1-9,11-4094 76 | switchport mode trunk 77 | channel-group 1 mode active 78 | ! 79 | interface Ethernet0/1 80 | switchport trunk encapsulation dot1q 81 | switchport trunk allowed vlan 1-9,11-4094 82 | switchport mode trunk 83 | channel-group 1 mode active 84 | ! 85 | interface Ethernet0/2 86 | shutdown 87 | duplex auto 88 | ! 89 | interface Ethernet0/3 90 | shutdown 91 | duplex auto 92 | ! 93 | interface Ethernet1/0 94 | shutdown 95 | duplex auto 96 | ! 97 | interface Ethernet1/1 98 | shutdown 99 | duplex auto 100 | ! 101 | interface Ethernet1/2 102 | shutdown 103 | duplex auto 104 | ! 105 | interface Ethernet1/3 106 | shutdown 107 | duplex auto 108 | ! 109 | interface Ethernet2/0 110 | shutdown 111 | duplex auto 112 | ! 113 | interface Ethernet2/1 114 | shutdown 115 | duplex auto 116 | ! 117 | interface Ethernet2/2 118 | shutdown 119 | duplex auto 120 | ! 121 | interface Ethernet2/3 122 | shutdown 123 | duplex auto 124 | ! 125 | interface Ethernet3/0 126 | shutdown 127 | duplex auto 128 | ! 129 | interface Ethernet3/1 130 | shutdown 131 | duplex auto 132 | ! 133 | interface Ethernet3/2 134 | shutdown 135 | duplex auto 136 | ! 137 | interface Ethernet3/3 138 | switchport access vlan 10 139 | switchport mode access 140 | ! 141 | interface Vlan10 142 | ip address 10.100.1.13 255.255.255.0 143 | no ip route-cache 144 | ! 145 | ! 146 | no ip http server 147 | ! 148 | ! 149 | ! 150 | ! 151 | snmp-server location FRA 152 | ! 153 | ! 154 | ! 155 | control-plane 156 | ! 157 | ! 158 | line con 0 159 | logging synchronous 160 | line aux 0 161 | line vty 1 4 162 | transport input ssh 163 | ! 164 | end -------------------------------------------------------------------------------- /device_configs/lab/s14-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 2106 bytes 4 | ! 5 | ! Last configuration change at 21:43:14 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname s14-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | no ip routing 33 | ! 34 | no ip cef 35 | ! 36 | ! 37 | no ip domain-lookup 38 | ip domain-name inxn.net 39 | no ipv6 cef 40 | ipv6 multicast rpf use-bgp 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | spanning-tree mode pvst 49 | spanning-tree extend system-id 50 | ! 51 | ! 52 | ! 53 | ! 54 | vlan internal allocation policy ascending 55 | lldp run 56 | ! 57 | ip ssh version 2 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | ! 67 | interface Port-channel1 68 | switchport 69 | switchport trunk encapsulation dot1q 70 | switchport trunk allowed vlan 1-9,11-4094 71 | switchport mode trunk 72 | ! 73 | interface Ethernet0/0 74 | switchport trunk encapsulation dot1q 75 | switchport trunk allowed vlan 1-9,11-4094 76 | switchport mode trunk 77 | channel-group 1 mode active 78 | ! 79 | interface Ethernet0/1 80 | switchport trunk encapsulation dot1q 81 | switchport trunk allowed vlan 1-9,11-4094 82 | switchport mode trunk 83 | channel-group 1 mode active 84 | ! 85 | interface Ethernet0/2 86 | shutdown 87 | duplex auto 88 | ! 89 | interface Ethernet0/3 90 | shutdown 91 | duplex auto 92 | ! 93 | interface Ethernet1/0 94 | shutdown 95 | duplex auto 96 | ! 97 | interface Ethernet1/1 98 | shutdown 99 | duplex auto 100 | ! 101 | interface Ethernet1/2 102 | shutdown 103 | duplex auto 104 | ! 105 | interface Ethernet1/3 106 | shutdown 107 | duplex auto 108 | ! 109 | interface Ethernet2/0 110 | shutdown 111 | duplex auto 112 | ! 113 | interface Ethernet2/1 114 | shutdown 115 | duplex auto 116 | ! 117 | interface Ethernet2/2 118 | shutdown 119 | duplex auto 120 | ! 121 | interface Ethernet2/3 122 | shutdown 123 | duplex auto 124 | ! 125 | interface Ethernet3/0 126 | shutdown 127 | duplex auto 128 | ! 129 | interface Ethernet3/1 130 | shutdown 131 | duplex auto 132 | ! 133 | interface Ethernet3/2 134 | shutdown 135 | duplex auto 136 | ! 137 | interface Ethernet3/3 138 | switchport access vlan 10 139 | switchport mode access 140 | ! 141 | interface Vlan10 142 | ip address 10.100.1.14 255.255.255.0 143 | no ip route-cache 144 | ! 145 | ! 146 | no ip http server 147 | ! 148 | ! 149 | ! 150 | ! 151 | snmp-server location DUS 152 | ! 153 | ! 154 | ! 155 | control-plane 156 | ! 157 | ! 158 | line con 0 159 | logging synchronous 160 | line aux 0 161 | line vty 1 4 162 | transport input ssh 163 | ! 164 | end -------------------------------------------------------------------------------- /device_configs/lab/s15-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 2106 bytes 4 | ! 5 | ! Last configuration change at 22:00:10 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname s15-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | no ip routing 33 | ! 34 | no ip cef 35 | ! 36 | ! 37 | no ip domain-lookup 38 | ip domain-name inxn.net 39 | no ipv6 cef 40 | ipv6 multicast rpf use-bgp 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | spanning-tree mode pvst 49 | spanning-tree extend system-id 50 | ! 51 | ! 52 | ! 53 | ! 54 | vlan internal allocation policy ascending 55 | lldp run 56 | ! 57 | ip ssh version 2 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | ! 67 | interface Port-channel1 68 | switchport 69 | switchport trunk encapsulation dot1q 70 | switchport trunk allowed vlan 1-9,11-4094 71 | switchport mode trunk 72 | ! 73 | interface Ethernet0/0 74 | switchport trunk encapsulation dot1q 75 | switchport trunk allowed vlan 1-9,11-4094 76 | switchport mode trunk 77 | channel-group 1 mode active 78 | ! 79 | interface Ethernet0/1 80 | switchport trunk encapsulation dot1q 81 | switchport trunk allowed vlan 1-9,11-4094 82 | switchport mode trunk 83 | channel-group 1 mode active 84 | ! 85 | interface Ethernet0/2 86 | shutdown 87 | duplex auto 88 | ! 89 | interface Ethernet0/3 90 | shutdown 91 | duplex auto 92 | ! 93 | interface Ethernet1/0 94 | shutdown 95 | duplex auto 96 | ! 97 | interface Ethernet1/1 98 | shutdown 99 | duplex auto 100 | ! 101 | interface Ethernet1/2 102 | shutdown 103 | duplex auto 104 | ! 105 | interface Ethernet1/3 106 | shutdown 107 | duplex auto 108 | ! 109 | interface Ethernet2/0 110 | shutdown 111 | duplex auto 112 | ! 113 | interface Ethernet2/1 114 | shutdown 115 | duplex auto 116 | ! 117 | interface Ethernet2/2 118 | shutdown 119 | duplex auto 120 | ! 121 | interface Ethernet2/3 122 | shutdown 123 | duplex auto 124 | ! 125 | interface Ethernet3/0 126 | shutdown 127 | duplex auto 128 | ! 129 | interface Ethernet3/1 130 | shutdown 131 | duplex auto 132 | ! 133 | interface Ethernet3/2 134 | shutdown 135 | duplex auto 136 | ! 137 | interface Ethernet3/3 138 | switchport access vlan 10 139 | switchport mode access 140 | ! 141 | interface Vlan10 142 | ip address 10.100.1.15 255.255.255.0 143 | no ip route-cache 144 | ! 145 | ! 146 | no ip http server 147 | ! 148 | ! 149 | ! 150 | ! 151 | snmp-server location ZUR 152 | ! 153 | ! 154 | ! 155 | control-plane 156 | ! 157 | ! 158 | line con 0 159 | logging synchronous 160 | line aux 0 161 | line vty 1 4 162 | transport input ssh 163 | ! 164 | end -------------------------------------------------------------------------------- /roles/cisco_validate/templates/validation_report.j2: -------------------------------------------------------------------------------- 1 | Validation Report for {{ inventory_hostname }}: 2 | 3 | Interface configuration issues: 4 | {% for interface in interfaces %} 5 | {#---- #} 6 | {#- initialize default values for variables #} 7 | {#---- #} 8 | {#---- #} 9 | {% set config_data = { 10 | "description": None, 11 | "vlan": None, 12 | "voicevlan": None, 13 | "nativevlan": None, 14 | "portmode": 'access', 15 | "adminstate": 'disabled', 16 | "poe": False, 17 | "cdp": True 18 | } %} 19 | {#---- #} 20 | {#- Load portprofile parameters if portprofile is used for interface #} 21 | {#---- #} 22 | {#---- #} 23 | {% if 'portprofile' in interfaces[interface].keys() %} 24 | {% for profile in portprofiles %} 25 | {% if profile.name == interfaces[interface]['portprofile'] %} 26 | {%- for parameter in config_data.keys() %} 27 | {% if parameter in profile %}{% set x=config_data.__setitem__(parameter, profile[parameter]) %}{% endif %} 28 | {% if parameter in interfaces[interface] %}{% set x=config_data.__setitem__(parameter, interfaces[interface][parameter]) %}{% endif %} 29 | {% endfor %} 30 | {% endif %} 31 | {% endfor %} 32 | {% else %} 33 | {#---- #} 34 | {#- Load interface parameters no portprofile is used for interface #} 35 | {#---- #} 36 | {#---- #} 37 | {%- for parameter in config_data.keys() %} 38 | {% if parameter in interfaces[interface] %}{% set x=config_data.__setitem__(parameter, interfaces[interface][parameter]) %}{% endif %} 39 | {% endfor %} 40 | {% endif %} 41 | {#---- #} 42 | {#- Compare actual and configured data for interface #} 43 | {#---- #} 44 | {#---- #} 45 | {%- for c in spec_result %} 46 | {%- for p in config_data.keys() %} 47 | {%- if c[p] is iterable and c[p] is not string %}{% set x=c.update({p:c[p]| join(',')}) %}{% endif %} 48 | {%- if c.name == interface and p in c and config_data[p] != c[p] %} 49 | {#- Ignore POE if not supported on switch #} 50 | {% if poe_supported is defined and poe_supported == false and p=='poe'%}{% else %} 51 | {{ interface }} has a mismatch for {{ p }} - intended: '{{ config_data[p] }}' actual: '{{ c[p] }}' 52 | {% endif %} 53 | {%- endif %} 54 | {%- endfor %} 55 | {%- endfor %} 56 | {#---- #} 57 | {#- Check interface state compared with intended config #} 58 | {#---- #} 59 | {#---- #} 60 | {%- set state_result = result.ansible_facts.napalm_interfaces %} 61 | {%- for i in state_result %} 62 | {%- if i == interface and 'is_up' in state_result[i]%} 63 | {%- if state_result[i].is_up == false and config_data.adminstate == 'enabled' %} 64 | interface {{ interface }} is down, but should be up 65 | {%- endif %} 66 | {% if state_result[i].is_up == True and config_data.adminstate == 'disabled' %} 67 | interface {{ interface }} is up, but should be admin disabled 68 | {% endif %} 69 | {%- endif %} 70 | {%- endfor %} 71 | {% endfor %} 72 | 73 | 74 | -------------------------------------------------------------------------------- /device_configs/lab/s11-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 2161 bytes 4 | ! 5 | ! Last configuration change at 22:03:06 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname s11-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | no ip routing 33 | ! 34 | no ip cef 35 | ! 36 | ! 37 | no ip domain-lookup 38 | ip domain-name inxn.net 39 | no ipv6 cef 40 | ipv6 multicast rpf use-bgp 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | spanning-tree mode pvst 49 | spanning-tree extend system-id 50 | ! 51 | ! 52 | ! 53 | ! 54 | vlan internal allocation policy ascending 55 | lldp run 56 | ! 57 | ip ssh version 2 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | ! 67 | interface Port-channel1 68 | switchport 69 | switchport trunk encapsulation dot1q 70 | switchport trunk allowed vlan 1-9,11-4094 71 | switchport mode trunk 72 | ! 73 | interface Ethernet0/0 74 | switchport trunk encapsulation dot1q 75 | switchport trunk allowed vlan 1-9,11-4094 76 | switchport mode trunk 77 | channel-group 1 mode active 78 | ! 79 | interface Ethernet0/1 80 | switchport trunk encapsulation dot1q 81 | switchport trunk allowed vlan 1-9,11-4094 82 | switchport mode trunk 83 | channel-group 1 mode active 84 | ! 85 | interface Ethernet0/2 86 | shutdown 87 | duplex auto 88 | ! 89 | interface Ethernet0/3 90 | shutdown 91 | duplex auto 92 | ! 93 | interface Ethernet1/0 94 | shutdown 95 | duplex auto 96 | ! 97 | interface Ethernet1/1 98 | shutdown 99 | duplex auto 100 | ! 101 | interface Ethernet1/2 102 | shutdown 103 | duplex auto 104 | ! 105 | interface Ethernet1/3 106 | shutdown 107 | duplex auto 108 | ! 109 | interface Ethernet2/0 110 | shutdown 111 | duplex auto 112 | ! 113 | interface Ethernet2/1 114 | shutdown 115 | duplex auto 116 | ! 117 | interface Ethernet2/2 118 | shutdown 119 | duplex auto 120 | ! 121 | interface Ethernet2/3 122 | shutdown 123 | duplex auto 124 | ! 125 | interface Ethernet3/0 126 | shutdown 127 | duplex auto 128 | ! 129 | interface Ethernet3/1 130 | shutdown 131 | duplex auto 132 | ! 133 | interface Ethernet3/2 134 | shutdown 135 | duplex auto 136 | ! 137 | interface Ethernet3/3 138 | switchport access vlan 10 139 | switchport mode access 140 | ! 141 | interface Vlan10 142 | mac-address aabb.cc80.0011 143 | ip address 10.100.1.11 255.255.255.0 144 | no ip route-cache 145 | ! 146 | ! 147 | no ip http server 148 | ! 149 | ! 150 | ! 151 | ! 152 | snmp-server location AMS 153 | ! 154 | ! 155 | ! 156 | control-plane 157 | ! 158 | ! 159 | line con 0 160 | logging synchronous 161 | line aux 0 162 | line vty 1 4 163 | transport input ssh 164 | ! 165 | ntp server 192.168.220.140 166 | end -------------------------------------------------------------------------------- /roles/cisco_device_provisioning/templates/provisioning.j2: -------------------------------------------------------------------------------- 1 | {% import 'provisioning_macros.j2' as prov %} 2 | 3 | service timestamps debug datetime msec 4 | service timestamps log datetime msec localtime 5 | service password-encryption 6 | service compress-config 7 | !service unsupported-transceiver 8 | ! 9 | hostname {{ inventory_hostname }} 10 | enable secret 0 {{ enable_secret }} 11 | aaa new-model 12 | ! 13 | ! 14 | aaa authentication login netlogin group tacacs+ local 15 | aaa authorization exec default group tacacs+ local if-authenticated 16 | aaa authorization exec netlogin if-authenticated 17 | aaa accounting send stop-record authentication failure 18 | aaa accounting exec netlogin start-stop group tacacs+ 19 | aaa accounting commands 1 default start-stop group tacacs+ 20 | aaa accounting commands 15 default start-stop group tacacs+ 21 | aaa accounting commands 15 neteng start-stop group tacacs+ 22 | aaa accounting network netlogin start-stop group tacacs+ 23 | aaa accounting system default start-stop group tacacs+ 24 | ! 25 | aaa session-id common 26 | clock timezone CET 1 0 27 | clock summer-time CET recurring last Sun Mar 2:00 last Sun Oct 3:00 28 | ! 29 | ! 30 | no ip domain-lookup 31 | ip domain-name {{ dnsdomain }} 32 | ! 33 | ! 34 | vtp mode transparent 35 | ! 36 | crypto key generate rsa mod 2048 37 | ! 38 | spanning-tree mode rapid-pvst 39 | spanning-tree extend system-id 40 | 41 | ip forward-protocol nd 42 | no ip http server 43 | ip http authentication local 44 | !no ip http secure-server 45 | ! 46 | ! 47 | ip ssh version 2 48 | logging trap debugging 49 | 50 | {% if users is defined %}{{ prov.set_users(users) }}{% endif %} 51 | {% if dnsservers is defined %}{{ prov.set_dnsservers(dnsservers) }}{% endif %} 52 | {% if snmp is defined %}{{ prov.set_snmp(snmp) }}{% endif %} 53 | {% if tacacs is defined %}{{ prov.set_tacacs(tacacs) }}{% endif %} 54 | {% if syslog is defined %}{{ prov.set_syslog(syslog) }}{% endif %} 55 | {% if ntp is defined %}{{ prov.set_ntp(ntp) }}{% endif %} 56 | {% if sw_mgmt_svi is defined %}{{ prov.set_mgmt_svi(sw_mgmt_svi) }}{% endif %} 57 | ! 58 | ! 59 | banner login ^C 60 | ****************************************************************** 61 | * * 62 | * You are now attempting to access the * PRIVATE * * 63 | * * 64 | * InterXion Network * 65 | * * 66 | * * * THIS SERVICE IS AVAILABLE TO AUTHORISED PERSONNEL ONLY * * * 67 | * * 68 | * *****UNAUTHORISED ACCESS IS STRICTLY FORBIDDEN****** * 69 | * * 70 | ******************************************************************^C 71 | ! 72 | line con 0 73 | password {{ console_password }} 74 | exec-timeout 10 75 | stopbits 1 76 | line vty 0 4 77 | transport input ssh 78 | accounting exec netlogin 79 | login authentication netlogin 80 | exec-timeout 10 81 | ! 82 | 83 | end 84 | -------------------------------------------------------------------------------- /roles/cisco_lldp_topo/README.md: -------------------------------------------------------------------------------- 1 | # cisco_lldp_topo 2 | Ansible role which generates a lldp_topo.png image containing the discovered network topology of all hosts selected in the playbook. 3 | 4 | Role description 5 | ----------------------- 6 | The role makes use of LLDP neighbor facts gathered by [Napalm](https://napalm-automation.net/) using the napalm_get_facts role. The facts are used to generate a [Graphviz](https://www.graphviz.org/) .dot file using a .j2 template.
7 | The template keeps track of already processed interfaces, so that there are no double connections in the graphs.
8 | The output of the template is used as stdin for executing the dot command which generates the image of the topology. 9 | The topology contains all participating hosts along with their connected interfaces.
10 | 11 | This role is currently only supported for Cisco IOL devices using 'Ethernet' naming of their interfaces. 12 | 13 | Output example 14 | -------------------- 15 | ``` 16 | $ ansible-playbook cisco_lldp_topo.yml 17 | 18 | PLAY [Generate LLDP topology playbook] ************************************************** 19 | 20 | TASK [cisco_lldp_topo : get LLDP information from device] ******************************* 21 | ok: [s14-iol] 22 | ok: [s13-iol] 23 | ok: [s11-iol] 24 | ok: [s15-iol] 25 | ok: [s12-iol] 26 | ok: [mgmt-iol] 27 | 28 | TASK [cisco_lldp_topo : generate .dot data] ********************************************* 29 | ok: [s11-iol -> 127.0.0.1] 30 | 31 | TASK [cisco_lldp_topo : generate lldp_topo.png] ***************************************** 32 | changed: [s11-iol -> 127.0.0.1] 33 | 34 | PLAY RECAP ****************************************************************************** 35 | mgmt-iol : ok=1 changed=0 unreachable=0 failed=0 36 | s11-iol : ok=3 changed=1 unreachable=0 failed=0 37 | s12-iol : ok=1 changed=0 unreachable=0 failed=0 38 | s13-iol : ok=1 changed=0 unreachable=0 failed=0 39 | s14-iol : ok=1 changed=0 unreachable=0 failed=0 40 | s15-iol : ok=1 changed=0 unreachable=0 failed=0 41 | ``` 42 | 43 | This generates the following .dot structure: 44 | 45 | ``` 46 | digraph G { 47 | splines=true; 48 | rankdir="LR"; 49 | overlap=scalexy; 50 | 51 | edge [ 52 | arrowhead="none" 53 | ]; 54 | 55 | node [style="rounded,filled,bold", shape=box, width=1.3, fontname="Arial"]; 56 | edge [fontsize=10]; 57 | "s14-iol.inxn.net" -> "mgmt-iol.inxn.net" [minlen=2 headlabel="Et1/0" taillabel="Et1/3"]; 58 | "s11-iol.inxn.net" -> "mgmt-iol.inxn.net" [minlen=2 headlabel="Et0/1" taillabel="Et1/3"]; 59 | "s13-iol.inxn.net" -> "mgmt-iol.inxn.net" [minlen=2 headlabel="Et0/3" taillabel="Et1/3"]; 60 | "mgmt-iol.inxn.net" -> "s15-iol.inxn.net" [minlen=2 headlabel="Et1/3" taillabel="Et1/2"]; 61 | "mgmt-iol.inxn.net" -> "s12-iol.inxn.net" [minlen=2 headlabel="Et1/3" taillabel="Et0/2"]; 62 | } 63 | ``` 64 | And this results in the following image: 65 | 66 | 67 | 68 | Please note: 69 | It is difficult to align grahpviz elements. Especially in larger topologies the result might look a bit messy. 70 | -------------------------------------------------------------------------------- /roles/cisco_vlan_service/templates/interface_macros.j2: -------------------------------------------------------------------------------- 1 | {% macro set_parameter(parameter, interface) %} 2 | {% if parameter == 'adminstate' %} 3 | {% if 'adminstate' in interface %} 4 | {% if interface['adminstate'] == True or interface['adminstate'] == "enabled" %}no shutdown 5 | {% elif interface['adminstate'] == False or interface['adminstate'] == "disabled" %}shutdown 6 | {% else %}shutdown 7 | {% endif %} 8 | {% else %}shutdown 9 | {% endif %} 10 | {% endif %} 11 | {# #} 12 | {% if parameter == 'description' %} 13 | {% if 'description' in interface and interface['description'] != None %} 14 | {% if interface['description']|length > 0 %}description {{ interface['description'] }} 15 | {% else %}no description 16 | {% endif %} 17 | {% if interface['description'] == None %}no description 18 | {% endif%} 19 | {% else %}no description 20 | {% endif %} 21 | {% endif %} 22 | {# #} 23 | {% if parameter == 'portmode' %} 24 | {% if interface['portmode'] != "trunk" %} 25 | switchport mode access 26 | no switchport trunk native vlan 27 | no switchport trunk allowed vlan 28 | no switchport trunk encapsulation dot1q 29 | {% if 'vlan' in interface %}switchport access vlan {{ interface['vlan'] }} 30 | {% else %}switchport access vlan 1 31 | {% endif %} 32 | spanning-tree portfast 33 | !spanning-tree bpduguard enable 34 | {% endif %} 35 | {% if interface['portmode'] == "trunk" %}switchport trunk encapsulation dot1q 36 | switchport mode trunk 37 | no spanning-tree portfast 38 | no spanning-tree bpduguard enable 39 | no switchport access vlan 40 | {% if 'vlan' in interface %}switchport trunk allowed vlan {{ interface['vlan'] }} 41 | {% else %}switchport trunk allowed vlan none 42 | {% endif %} 43 | {% if 'nativevlan' in interface %}switchport trunk native vlan {{ interface['nativevlan'] }} 44 | {% else %}no switchport trunk native vlan 45 | {% endif %} 46 | {% endif %} 47 | {% endif %} 48 | {# #} 49 | {% if parameter == 'voicevlan' %} 50 | {% if 'voicevlan' in interface %} 51 | {% if interface['voicevlan'] == None %} 52 | no switchport voice vlan 53 | {% else %} 54 | switchport voice vlan {{ interface['voicevlan'] }} 55 | {% endif %} 56 | {% else %} 57 | no switchport voice vlan 58 | {% endif %} 59 | {% endif %} 60 | {# #} 61 | {% if parameter == 'poe' %} 62 | {% if 'poe_supported' == True %} 63 | {% if 'poe' in interface %} 64 | {% if interface['poe'] %}power inline auto 65 | {% endif %} 66 | {% if not interface['poe'] %}power inline never 67 | {% endif %} 68 | {% endif %} 69 | {% endif %} 70 | {% endif %} 71 | {# #} 72 | {% if parameter == 'cdp' %} 73 | {% if 'cdp' in interface %} 74 | {% if interface['cdp'] %}cdp enable 75 | {% endif %} 76 | {% if not interface['cdp'] %}no cdp enable 77 | {% endif %} 78 | {% else %}cdp enable 79 | {% endif %} 80 | {% endif %} 81 | {# #} 82 | {% if parameter == 'portsecurity' %} 83 | {% if 'portsecurity' in interface %} 84 | {% if interface['portsecurity'] == "none" %}no switchport port-security 85 | {% elif interface['portsecurity'] == 'sticky' %} 86 | switchport port-security 87 | switchport port-security mac-address sticky 88 | switchport port-security maximum 1 89 | {% else %} 90 | switchport port-security 91 | switchport port-security mac-address {{ interface['portsecurity'] }} 92 | {% endif %} 93 | {% else %} 94 | no switchport port-security 95 | no switchport port-security mac-address 96 | no switchport port-security maximum 97 | {% endif %} 98 | {% endif %} 99 | {# #} 100 | {% if parameter == 'customstatements' %} 101 | {% if 'customstatements' in interface %} 102 | {% for statement in interface['customstatements'] %} 103 | {{ statement }} 104 | {% endfor %} 105 | {% endif %} 106 | {% endif %} 107 | {% endmacro %} -------------------------------------------------------------------------------- /roles/cisco_validate/README.md: -------------------------------------------------------------------------------- 1 | # cisco_validate 2 | Ansible role which generates a validation report containing the results of a config check which compares the live config of the interfaces of the switch, with the intented configuration. 3 | 4 | Role description 5 | ----------------------- 6 | The role makes use of running config and interface facts gathered by [Napalm](https://napalm-automation.net/) using the napalm_get_facts role.
7 | The facts are used to generate a text file per device containining any found issues comparing the live and intended configuration.
8 | The role makes use of the [validation_report.j2](../roles/cisco_validate/templates/validation_report.j2) which is populated by the results of a parse_cli filter called: [interface_config.spec](../roles/cisco_validate/tasks/interface_config.spec), which reads the config of the individual interfaces and abstracts the results to match the definitions as mentioned in the hostvars and portprofiles for the device.
9 | It also checks if the interfaces which should be up, are actually up, and the ones that are configured as down are actually down.
10 |
11 | This role is currently only supported for Cisco IOL devices using 'Ethernet' naming of their interfaces.
12 | 13 | Example 14 | ------- 15 | there is a switch called s12-iol. 16 | It has some interfaces configured as follows in the hostvars file: 17 | ``` 18 | Ethernet1/0: 19 | portprofile: office 20 | Ethernet1/1: 21 | portprofile: office 22 | Ethernet1/2: 23 | portprofile: office 24 | ``` 25 | we can change the variables to for instance: 26 | ``` 27 | Ethernet1/0: 28 | portprofile: wifi_accesspoint 29 | Ethernet1/1: 30 | portprofile: office 31 | description: my desktop 32 | Ethernet1/2: 33 | portprofile: disabled 34 | ``` 35 | Eample run:
36 | We can run the provisioning playbook using only the validation tag to avoid configuring the switch and only running the validation.
37 | 38 | ```~/ansible_lab$ ansible-playbook cisco_provisioning.yml --limit s12-iol --tags validate 39 | 40 | PLAY [Device and service provisioning for cisco devices] ********************************************************** 41 | 42 | TASK [cisco_validate : get config info from device] *************************************************************** 43 | ok: [s12-iol] 44 | 45 | TASK [cisco_validate : parse received config info] **************************************************************** 46 | ok: [s12-iol] 47 | 48 | TASK [cisco_validate : Write validation report to file] *********************************************************** 49 | ok: [s12-iol] 50 | 51 | PLAY RECAP ******************************************************************************************************** 52 | s12-iol : ok=3 changed=0 unreachable=0 failed=0 53 | ``` 54 | 55 | This will produce a report called: `s12-iol_validation_report.txt`.
56 |
57 | The file will contain all detected mismatches: 58 | ```:~/ansible_lab$ cat s12-iol_validation_report.txt 59 | Validation Report for s12-iol: 60 | 61 | Interface configuration issues: 62 | Ethernet1/0 has a mismatch for nativevlan - intended: '998' actual: '' 63 | Ethernet1/0 has a mismatch for description - intended: 'port configuration for WIFI accesspoints' actual: 'port configuration for Office desktops and phones' 64 | Ethernet1/0 has a mismatch for portmode - intended: 'trunk' actual: 'access' 65 | Ethernet1/0 has a mismatch for vlan - intended: '998,999' actual: '15' 66 | Ethernet1/0 has a mismatch for voicevlan - intended: '' actual: '39' 67 | Ethernet1/1 has a mismatch for description - intended: 'my desktop' actual: 'port configuration for Office desktops and phones' 68 | Ethernet1/2 has a mismatch for adminstate - intended: 'disabled' actual: 'enabled' 69 | Ethernet1/2 has a mismatch for description - intended: 'disabled' actual: 'port configuration for Office desktops and phones' 70 | Ethernet1/2 has a mismatch for vlan - intended: '2' actual: '15' 71 | Ethernet1/2 has a mismatch for voicevlan - intended: '' actual: '39' 72 | Ethernet1/2 has a mismatch for cdp - intended: 'True' actual: 'False' 73 | interface Ethernet1/2 is up, but should be admin disabled 74 | ``` 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ansible_lab 2 | Ansible lab environment as part of the [ipspace.net](https://www.ipspace.net) [Network automation course](https://www.ipspace.net/Building_Network_Automation_Solutions). 3 | 4 | # Table of contents 5 | 1. [Environment description](#environment_description) 6 | 2. [Topology description](#topology_description) 7 | 3. [Ansible configuration](#ansible_configuration) 8 | 4. [Implemented playbooks](#implemented_playbooks) 9 | 10 | 11 | Environment description 12 | ----------------------- 13 | The lab is built in a VMware 6.5 ESXi host. 14 | It consists of two virtual servers: 15 | 16 | **Eve-NG:** 17 | This is a network virtualisation platform which an interface to building virtual network topologies of many vendors of networking equipment. [Eve-NG](http://eve-ng.net/) 18 | 19 | **Linux server:** 20 | This server hosts the ansible lab environment. It is running Ubuntu 18.04 LTS, and Ansible 2.7 is installed. 21 | 22 | Both servers have two NICs, which are both are connected through a separate standard vswitch.
23 | The first NIC has a connection to the corporate network, and provides connectivity to the internet using NAT provided by the corporate firewall infrastructure.
24 | The second NIC is connected to a vswitch which only connects the Linux server with the Eve-NG server to allow access to the switches running on Eve-NG.
25 | 26 | Local vswitch topology:
27 | 28 | 29 | Uplink vswitch topology:
30 | 31 | 32 | Topology description 33 | -------------------- 34 | On Eve-NG there runs a virtual network environment with the following switches: 35 | 36 | | hostname | IP | Description | 37 | | :------------ |:-------------| :-----| 38 | | s11-iol | 10.100.1.11 | Cisco IOL virtual switch | 39 | | s12-iol | 10.100.1.12 | Cisco IOL virtual switch | 40 | | s13-iol | 10.100.1.13 | Cisco IOL virtual switch | 41 | | s14-iol | 10.100.1.14 | Cisco IOL virtual switch | 42 | | s15-iol | 10.100.1.15 | Cisco IOL virtual switch | 43 | | mgmt-iol | 10.100.1.100 | Cisco IOL virtual switch used for aggregation and uplink to ansible host| 44 | | erikbuntu | 10.100.1.20 | Ansible host| 45 | 46 | All switches have a interface in a switch management vlan, which is switched through the management switch (mgmt-iol) to the outside, towards the Ansible host. 47 | 48 | 49 | 50 | 51 | 52 | Ansible configuration 53 | ---------------------- 54 | At the start of the course, the Ansible configuration is still basic.
55 | Here is an overview of the files currently in use: 56 | 57 | | File | Description | 58 | | :---- | :----- | 59 | | ansible.cfg | Standard ansible configuration file, with tweaks for vault and inventory location | 60 | | inventory | Basic static inventory file listing all switches in the lab environment| 61 | | group_vars/lab/vars | placeholder for global variables related to the lab group| 62 | | group_vars/lab/vault| placeholder for vault variables related to the lab group (currently contains ssh password for Cisco switches)| 63 | 64 | Example of raw adhoc command: 65 | ``` 66 | erikr@erikbuntu:~/ansible_lab$ ansible -m raw -a "show run | i hostname" lab 67 | s12-iol | CHANGED | rc=0 >> 68 | hostname s12-iol 69 | Shared connection to s12-iol closed. 70 | 71 | 72 | s14-iol | CHANGED | rc=0 >> 73 | hostname s14-iol 74 | Shared connection to s14-iol closed. 75 | 76 | 77 | s11-iol | CHANGED | rc=0 >> 78 | hostname s11-iol 79 | Shared connection to s11-iol closed. 80 | 81 | 82 | s13-iol | CHANGED | rc=0 >> 83 | hostname s13-iol 84 | Shared connection to s13-iol closed. 85 | 86 | 87 | s15-iol | CHANGED | rc=0 >> 88 | hostname s15-iol 89 | Shared connection to s15-iol closed. 90 | ``` 91 | 92 | 93 | Implemented playbooks 94 | --------------------- 95 | 96 | **[backup_config.yml:](../../blob/master/backup_config.yml)** 97 | Playbook which reads config from all hosts and stores it in the device_config directory. Changes are also commited to the repository 98 | 99 | **[napalm_get_facts.yml:](../../blob/master/napalm_get_facts.yml)** 100 | Basic playbook to get napalm facts from devices. A filter can be specified when running the playbook. 101 | 102 | **[cisco_lldp_topo.yml:](../../blob/master/cisco_lldp_topo.yml)** (2nd course assignment) 103 | Playbook wheach reads config from all hosts and tries to build an LLDP topology graph using graphviz 104 | 105 | **[cisco_provisioning.yml:](../../blob/master/cisco_provisioning.yml)** (3rd/4th course assignment) 106 | Playbook which generates and installs basic cisco device config. 107 | 108 | **[cisco_vlan_service.yml:](../../blob/master/cisco_vlan_service.yml)** (3rd/4th course assignment) 109 | Playbook which generates and installs cisco config for provisioning a layer 2 vlan service per port. 110 | 111 | **[cisco_validate.yml:](../../blob/master/cisco_validate.yml)** (3rd/4th course assignment) 112 | Playbook which does a config check to see if the live config is as intended. 113 | 114 | * More to be added as the course progresses 115 | -------------------------------------------------------------------------------- /device_configs/lab/s01-iol: -------------------------------------------------------------------------------- 1 | Building configuration... 2 | 3 | Current configuration : 4996 bytes 4 | ! 5 | ! Last configuration change at 22:33:49 GMT Sat Jan 5 2019 6 | ! 7 | version 15.1 8 | service timestamps debug datetime msec 9 | service timestamps log datetime msec 10 | no service password-encryption 11 | service compress-config 12 | ! 13 | hostname s01-iol 14 | ! 15 | boot-start-marker 16 | boot-end-marker 17 | ! 18 | ! 19 | ! 20 | username ansible privilege 15 password 0 ******** 21 | aaa new-model 22 | ! 23 | ! 24 | aaa authorization exec default local if-authenticated 25 | ! 26 | ! 27 | ! 28 | ! 29 | ! 30 | aaa session-id common 31 | clock timezone GMT 0 0 32 | no ip routing 33 | ! 34 | no ip cef 35 | ! 36 | ! 37 | no ip domain-lookup 38 | ip domain-name inxn.net 39 | no ipv6 cef 40 | ipv6 multicast rpf use-bgp 41 | ! 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | spanning-tree mode pvst 49 | spanning-tree extend system-id 50 | ! 51 | ! 52 | ! 53 | ! 54 | vlan internal allocation policy ascending 55 | lldp run 56 | ! 57 | ip ssh version 2 58 | ! 59 | ! 60 | ! 61 | ! 62 | ! 63 | ! 64 | ! 65 | ! 66 | ! 67 | interface Port-channel1 68 | no ip address 69 | ! 70 | interface Port-channel18 71 | switchport 72 | switchport trunk encapsulation dot1q 73 | switchport trunk allowed vlan 1-9,11-4094 74 | switchport mode trunk 75 | ! 76 | interface Port-channel17 77 | switchport 78 | switchport trunk encapsulation dot1q 79 | switchport trunk allowed vlan 1-9,11-4094 80 | switchport mode trunk 81 | ! 82 | interface Port-channel16 83 | switchport 84 | switchport trunk encapsulation dot1q 85 | switchport trunk allowed vlan 1-9,11-15,17-4094 86 | switchport mode trunk 87 | ! 88 | interface Port-channel15 89 | switchport 90 | switchport trunk encapsulation dot1q 91 | switchport trunk allowed vlan 1-9,11-15,17-4094 92 | switchport mode trunk 93 | ! 94 | interface Port-channel14 95 | switchport 96 | switchport trunk encapsulation dot1q 97 | switchport trunk allowed vlan 1-9,11-4094 98 | switchport mode trunk 99 | ! 100 | interface Port-channel13 101 | switchport 102 | switchport trunk encapsulation dot1q 103 | switchport trunk allowed vlan 1-9,11-4094 104 | switchport mode trunk 105 | ! 106 | interface Port-channel12 107 | switchport 108 | switchport trunk encapsulation dot1q 109 | switchport trunk allowed vlan 1-9,11-4094 110 | switchport mode trunk 111 | ! 112 | interface Port-channel11 113 | switchport 114 | switchport trunk encapsulation dot1q 115 | switchport trunk allowed vlan 1-9,11-4094 116 | switchport mode trunk 117 | ! 118 | interface Ethernet0/0 119 | switchport trunk encapsulation dot1q 120 | switchport trunk allowed vlan 1-9,11-4094 121 | switchport mode trunk 122 | ! 123 | interface Ethernet0/1 124 | switchport trunk encapsulation dot1q 125 | switchport trunk allowed vlan 1-9,11-4094 126 | switchport mode trunk 127 | ! 128 | interface Ethernet0/2 129 | switchport trunk encapsulation dot1q 130 | switchport trunk allowed vlan 1-9,11-4094 131 | switchport mode trunk 132 | ! 133 | interface Ethernet0/3 134 | switchport trunk encapsulation dot1q 135 | switchport trunk allowed vlan 1-9,11-4094 136 | switchport mode trunk 137 | ! 138 | interface Ethernet1/0 139 | switchport trunk encapsulation dot1q 140 | switchport trunk allowed vlan 1-9,11-15,17-4094 141 | switchport mode trunk 142 | ! 143 | interface Ethernet1/1 144 | switchport trunk encapsulation dot1q 145 | switchport trunk allowed vlan 1-9,11-15,17-4094 146 | switchport mode trunk 147 | ! 148 | interface Ethernet1/2 149 | switchport trunk encapsulation dot1q 150 | switchport trunk allowed vlan 1-9,11-4094 151 | switchport mode trunk 152 | ! 153 | interface Ethernet1/3 154 | switchport trunk encapsulation dot1q 155 | switchport trunk allowed vlan 1-9,11-4094 156 | switchport mode trunk 157 | ! 158 | interface Ethernet2/0 159 | switchport trunk encapsulation dot1q 160 | switchport trunk allowed vlan 1-9,11-4094 161 | switchport mode trunk 162 | ! 163 | interface Ethernet2/1 164 | switchport trunk encapsulation dot1q 165 | switchport trunk allowed vlan 1-9,11-4094 166 | switchport mode trunk 167 | ! 168 | interface Ethernet2/2 169 | switchport trunk encapsulation dot1q 170 | switchport trunk allowed vlan 1-9,11-4094 171 | switchport mode trunk 172 | ! 173 | interface Ethernet2/3 174 | switchport trunk encapsulation dot1q 175 | switchport trunk allowed vlan 1-9,11-4094 176 | switchport mode trunk 177 | ! 178 | interface Ethernet3/0 179 | switchport trunk encapsulation dot1q 180 | switchport trunk allowed vlan 1-9,11-15,17-4094 181 | switchport mode trunk 182 | ! 183 | interface Ethernet3/1 184 | switchport trunk encapsulation dot1q 185 | switchport trunk allowed vlan 1-9,11-15,17-4094 186 | switchport mode trunk 187 | ! 188 | interface Ethernet3/2 189 | switchport trunk encapsulation dot1q 190 | switchport trunk allowed vlan 1-9,11-4094 191 | switchport mode trunk 192 | ! 193 | interface Ethernet3/3 194 | switchport trunk encapsulation dot1q 195 | switchport trunk allowed vlan 1-9,11-4094 196 | switchport mode trunk 197 | ! 198 | interface Ethernet4/0 199 | shutdown 200 | duplex auto 201 | ! 202 | interface Ethernet4/1 203 | shutdown 204 | duplex auto 205 | ! 206 | interface Ethernet4/2 207 | shutdown 208 | duplex auto 209 | ! 210 | interface Ethernet4/3 211 | shutdown 212 | duplex auto 213 | ! 214 | interface Ethernet5/0 215 | shutdown 216 | duplex auto 217 | ! 218 | interface Ethernet5/1 219 | shutdown 220 | duplex auto 221 | ! 222 | interface Ethernet5/2 223 | shutdown 224 | duplex auto 225 | ! 226 | interface Ethernet5/3 227 | shutdown 228 | duplex auto 229 | ! 230 | interface Ethernet6/0 231 | shutdown 232 | duplex auto 233 | ! 234 | interface Ethernet6/1 235 | shutdown 236 | duplex auto 237 | ! 238 | interface Ethernet6/2 239 | shutdown 240 | duplex auto 241 | ! 242 | interface Ethernet6/3 243 | shutdown 244 | duplex auto 245 | ! 246 | interface Ethernet7/0 247 | shutdown 248 | duplex auto 249 | ! 250 | interface Ethernet7/1 251 | shutdown 252 | duplex auto 253 | ! 254 | interface Ethernet7/2 255 | shutdown 256 | duplex auto 257 | ! 258 | interface Ethernet7/3 259 | switchport access vlan 10 260 | switchport mode access 261 | ! 262 | interface Vlan10 263 | mac-address aabb.cc80.0001 264 | ip address 10.100.1.1 255.255.255.0 265 | ! 266 | ! 267 | no ip http server 268 | ! 269 | ! 270 | ! 271 | ! 272 | ! 273 | ! 274 | ! 275 | control-plane 276 | ! 277 | ! 278 | line con 0 279 | logging synchronous 280 | line aux 0 281 | line vty 1 4 282 | transport input ssh 283 | ! 284 | end -------------------------------------------------------------------------------- /roles/cisco_device_provisioning/README.md: -------------------------------------------------------------------------------- 1 | Cisco switch provisioning 2 | ------------------------- 3 | 4 | Provisioning is done with the [cisco_provisioning.yml](../../cisco_provisioning.yml) playbook.
5 | This playbook calls 3 roles: 6 | * cisco_device_provisioning 7 | * cisco_vlan_service 8 | * cisco_validate 9 | 10 | Together these roles generate and push a configuration for operating as a Layer2 switch, and a per port configuration for providing a vlan service for connected devices.
11 | The settings for the interfaces are configured by portprofiles, which are abstracted sets of commands which are used to build an interface config.
12 | Afterwards the configured vlan service is validated. This means that Ansible checks the live config and compares it with the defined variables of the device.

13 | 14 | Below is a description of how the datamodel is built, to provide a flexible method of configuring switches and Layer 2 interfaces hosted on these switches.
15 | 16 | Usage: 17 | 18 | The playbook can be run using tags, this means that you can optionally run only a single or multiple roles. The available tags are `device`, `service` and `validate`.
19 | For example:
20 | `ansible-playbook cisco_provisioning.yml`
21 | Will run all roles (device provisioning, vlan provisioning and config validation for all devices for the groups specified in the playbook.
22 | `ansible-playbook cisco_provisioning.yml --tags validate --limit s12-iol`
23 | Will only run the config validation role for the device named s12-iol.

24 | 25 | 26 | Device provisioning 27 | ------------------- 28 | 29 | The global configuration is generated by the [provisioning.j2](../../roles/cisco_device_provisioning/templates/provisioning.j2) template that configures basic device settings based on variables per Ansible group.
30 | Generic variables applicable to any group can be placed in [ansible_lab/group_vars/all/vars file](../../group_vars/all/vars). 31 |

32 | An example group_vars containing all options file can be found at: [ansible_lab/group_vars/lab/vars](../../group_vars/lab/vars) 33 | 34 | Implemented variables: 35 | 36 | 37 | 42 | 44 | 45 | 48 | 50 | 55 | 60 | 62 | 63 | 68 | 72 |
Variable nameExampleDescription
snmp
snmp:
 38 |   - server: 192.168.44.1
 39 |     community: public
 40 |     version: 2c
 41 |     access: readonly
SNMP servers and communities. Access can be readonly/readwrite. When ommited access will be readwrite
syslog
syslog:
 43 |   - server: 192.168.1.1
Syslog servers
dnsdomain
dnsdomain: inxn.net
DNS domain name
dnsservers
dnsservers:
 46 |   - 8.8.8.8
 47 |   - 4.4.4.4
DNS lookup servers
ntp
ntp:
 49 |   - server: 192.168.1.1
NTP servers
sw_mgmt_svi
sw_mgmt_svi:
 51 |  - vlan: 10
 52 |    ip: "{{ ansible_host_ip }}"
 53 |    netmask: 255.255.255.0
 54 |    default_gw: 10.1.100.1
SVI for switch management. Generates a vlan interface (SVI) for inband management. It will add a default gateway and set source-interfaces for various protocol. (A bit shaky, since this interface needs to be present any way to access the device in the lab.)
users
users:
 56 |   - name: ansible
 57 |     password: "{{ ansible_ssh_pass }}"
 58 |   - name: netuser
 59 |     password: bladiebla
Device user authentication
console_password
 61 | console_password: "{{ vault_console_pass }}"
Serial console password
enable_secret
enable_secret: "{{ vault_enable_secret }}"
Cisco enable secret
tacacs
tacacs:
 64 |   - server: 192.168.1.1
 65 |     key: "{{ vault_cisco_tacacs_key }}"
 66 |   - server: 192.168.1.2
 67 |     key: "{{ vault_cisco_tacacs_key }}"
Tacacs authentication settings
vlans
vlans:
 69 |   - cctv: 411
 70 |   - ipphone: 39
 71 |   - office: 15
List of known VLANs on the network
73 | 74 | 75 | VLAN service provisioning 76 | ------------------------- 77 | 78 | Each interface on the siwtch provides a vlan service for the connected device.
79 | There are many different device types which can be connected to the switch, which can have different ethernet switching requirements. To group the required statements for configuring a port, a port profile can be created, so that the configuration per port stays compact, without redundant information. 80 | 81 | * The port profiles are specified in the group_vars file of the related group. 82 | * Portprofiles are assigned in the hostvars file of the switch. Each interface can list a single portprofile (or none). 83 | * Variables in the portprofile can be overwritten in the hostvars file. 84 | 85 | Some possible (fictional) examples of portprofiles, which are written in the group_vars file: 86 | 87 | 88 | 119 |
ExampleComments
 89 |   - name: cctv
 90 |     description: CCTV device
 91 |     portmode: access
 92 |     vlan: 11
 93 |     portsecurity: sticky
 94 |     poe: True
 95 |     cdp: False
port config for a CCTV device. Untagged interface in vlan 11, using sticky mac, and provides PoE for the camera. 96 |
 97 |   - name: office
 98 |     portmode: access
 99 |     vlan: 15
100 |     voicevlan: 39
101 |     poe: True
102 |     cdp: True
Basic office port having a voice vlan and cdp for connected IP phone. No port security configured to allow BYOD. 103 |
104 |   - name: wifi_ap
105 |     description: WIFI Accesspoint
106 |     portmode: trunk
107 |     vlan: 100,101
108 |     nativevlan: 101
109 |     poe: True
110 |     cdp: False
Configuration for a WIFI accesspoint. It has tagging enabled, using a native vlan for management of the AP. PoE is required for powering the device. 111 |
112 |   - name: lab_uplink_port
113 |     description: Uplink port
114 |     portmode: trunk
115 |     vlan: all
116 |     poe: False
117 |     cdp: True
Trunk port as a uplink to the spine switch. 118 |
120 | 121 | The hostvars for the interfaces on a switch can look like following: 122 | ``` 123 | interfaces: 124 | Ethernet0/0: 125 | portprofile: lab_uplink_port 126 | Ethernet0/1: 127 | portprofile: cctv 128 | Ethernet0/2: 129 | description: Office file server 130 | portprofile: office 131 | poe: False 132 | Ethernet0/3: 133 | portprofile: office 134 | Ethernet0/4: 135 | portprofile: office 136 | Ethernet0/5: 137 | description: AP ground floor 138 | portprofile: wifi_ap 139 | Ethernet0/6: 140 | description: AP first floor 141 | portprofile: wifi_ap 142 | Ethernet0/7: 143 | portprofile: disabled 144 | ``` 145 | 146 | This is a list of all variables currently available: 147 | 148 | |Name | Possible values | Default | description | 149 | | -- | -- | -- | -- | 150 | |adminstate | enabled / disabled | disabled | Administrative state of the port | 151 | |description | any string | empty | Port description | 152 | |portmode | access / trunk | access | Port tagging | 153 | |vlan | number(1) / range(1,2,3-6) / none / all | required | VLAN is used for both access and trunk ports, can be noted any way that is also used on CLI | 154 | |voicevlan | 1-4095 | no voicevlan | Switchport voice vlan statement | 155 | |nativevlan | 2-4095 | no native vlan(1) | native vlan, only used in conjunction with port mode trunk | 156 | |poe | Yes / True / No / False | No | Enable Power over Ethernet on the port | 157 | |cdp | Yes / True / No / False | Yes | Enable Cisco Discovery Protocol on the Port | 158 | |portsecurity | none / sticky / aaaa.bbbb.cccc | none | Assigns port security to the port. This can be a single sticky address, or a specified MAC address | 159 | |customstatements | any cisco statement | none | Allows a list of custom config statements to add to the port | 160 | 161 | The required config statements are generated with help of a jinja template file [port_config.j2](../../roles/cisco_vlan_service/templates/port_config.j2)
162 | The template generates known VLANs specified in the group_vars, and then it loops through the individual interfaces.
163 | Each variable has its own macro which is included from [interface_macros.j2](../../roles/cisco_vlan_service/templates/interface_macros.j2) to keep the template nice and tidy. 164 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | # config file for ansible -- https://ansible.com/ 2 | # =============================================== 3 | 4 | # nearly all parameters can be overridden in ansible-playbook 5 | # or with command line flags. ansible will read ANSIBLE_CONFIG, 6 | # ansible.cfg in the current working directory, .ansible.cfg in 7 | # the home directory or /etc/ansible/ansible.cfg, whichever it 8 | # finds first 9 | 10 | [defaults] 11 | 12 | # some basic default values... 13 | 14 | inventory = /home/erikr/ansible_lab/inventory 15 | library = /usr/local/lib/python2.7/dist-packages/napalm_ansible 16 | #module_utils = /usr/share/my_module_utils/ 17 | #remote_tmp = ~/.ansible/tmp 18 | #local_tmp = ~/.ansible/tmp 19 | #plugin_filters_cfg = /etc/ansible/plugin_filters.yml 20 | #forks = 5 21 | #poll_interval = 15 22 | #sudo_user = root 23 | #ask_sudo_pass = True 24 | #ask_pass = True 25 | #transport = smart 26 | #remote_port = 22 27 | #module_lang = C 28 | #module_set_locale = False 29 | 30 | # plays will gather facts by default, which contain information about 31 | # the remote system. 32 | # 33 | # smart - gather by default, but don't regather if already gathered 34 | # implicit - gather by default, turn off with gather_facts: False 35 | # explicit - do not gather by default, must say gather_facts: True 36 | #gathering = implicit 37 | 38 | # This only affects the gathering done by a play's gather_facts directive, 39 | # by default gathering retrieves all facts subsets 40 | # all - gather all subsets 41 | # network - gather min and network facts 42 | # hardware - gather hardware facts (longest facts to retrieve) 43 | # virtual - gather min and virtual facts 44 | # facter - import facts from facter 45 | # ohai - import facts from ohai 46 | # You can combine them using comma (ex: network,virtual) 47 | # You can negate them using ! (ex: !hardware,!facter,!ohai) 48 | # A minimal set of facts is always gathered. 49 | #gather_subset = all 50 | 51 | # some hardware related facts are collected 52 | # with a maximum timeout of 10 seconds. This 53 | # option lets you increase or decrease that 54 | # timeout to something more suitable for the 55 | # environment. 56 | # gather_timeout = 10 57 | 58 | # Ansible facts are available inside the ansible_facts.* dictionary 59 | # namespace. This setting maintains the behaviour which was the default prior 60 | # to 2.5, duplicating these variables into the main namespace, each with a 61 | # prefix of 'ansible_'. 62 | # This variable is set to True by default for backwards compatibility. It 63 | # will be changed to a default of 'False' in a future release. 64 | # ansible_facts. 65 | # inject_facts_as_vars = True 66 | 67 | # additional paths to search for roles in, colon separated 68 | #roles_path = /etc/ansible/roles 69 | 70 | # uncomment this to disable SSH key host checking 71 | #host_key_checking = False 72 | 73 | # change the default callback, you can only have one 'stdout' type enabled at a time. 74 | #stdout_callback = skippy 75 | 76 | 77 | ## Ansible ships with some plugins that require whitelisting, 78 | ## this is done to avoid running all of a type by default. 79 | ## These setting lists those that you want enabled for your system. 80 | ## Custom plugins should not need this unless plugin author specifies it. 81 | 82 | # enable callback plugins, they can output to stdout but cannot be 'stdout' type. 83 | #callback_whitelist = timer, mail 84 | 85 | # Determine whether includes in tasks and handlers are "static" by 86 | # default. As of 2.0, includes are dynamic by default. Setting these 87 | # values to True will make includes behave more like they did in the 88 | # 1.x versions. 89 | #task_includes_static = False 90 | #handler_includes_static = False 91 | 92 | # Controls if a missing handler for a notification event is an error or a warning 93 | #error_on_missing_handler = True 94 | 95 | # change this for alternative sudo implementations 96 | #sudo_exe = sudo 97 | 98 | # What flags to pass to sudo 99 | # WARNING: leaving out the defaults might create unexpected behaviours 100 | #sudo_flags = -H -S -n 101 | 102 | # SSH timeout 103 | #timeout = 10 104 | 105 | # default user to use for playbooks if user is not specified 106 | # (/usr/bin/ansible will use current user as default) 107 | #remote_user = root 108 | 109 | # logging is off by default unless this path is defined 110 | # if so defined, consider logrotate 111 | #log_path = /var/log/ansible.log 112 | 113 | # default module name for /usr/bin/ansible 114 | #module_name = command 115 | 116 | # use this shell for commands executed under sudo 117 | # you may need to change this to bin/bash in rare instances 118 | # if sudo is constrained 119 | #executable = /bin/sh 120 | 121 | # if inventory variables overlap, does the higher precedence one win 122 | # or are hash values merged together? The default is 'replace' but 123 | # this can also be set to 'merge'. 124 | #hash_behaviour = replace 125 | 126 | # by default, variables from roles will be visible in the global variable 127 | # scope. To prevent this, the following option can be enabled, and only 128 | # tasks and handlers within the role will see the variables there 129 | #private_role_vars = yes 130 | 131 | # list any Jinja2 extensions to enable here: 132 | #jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n 133 | 134 | # if set, always use this private key file for authentication, same as 135 | # if passing --private-key to ansible or ansible-playbook 136 | #private_key_file = /path/to/file 137 | 138 | # If set, configures the path to the Vault password file as an alternative to 139 | # specifying --vault-password-file on the command line. 140 | vault_password_file = /home/erikr/ansible_lab/.vault_pass.txt 141 | 142 | # format of string {{ ansible_managed }} available within Jinja2 143 | # templates indicates to users editing templates files will be replaced. 144 | # replacing {file}, {host} and {uid} and strftime codes with proper values. 145 | #ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host} 146 | # {file}, {host}, {uid}, and the timestamp can all interfere with idempotence 147 | # in some situations so the default is a static string: 148 | #ansible_managed = Ansible managed 149 | 150 | # by default, ansible-playbook will display "Skipping [host]" if it determines a task 151 | # should not be run on a host. Set this to "False" if you don't want to see these "Skipping" 152 | # messages. NOTE: the task header will still be shown regardless of whether or not the 153 | # task is skipped. 154 | #display_skipped_hosts = True 155 | 156 | # by default, if a task in a playbook does not include a name: field then 157 | # ansible-playbook will construct a header that includes the task's action but 158 | # not the task's args. This is a security feature because ansible cannot know 159 | # if the *module* considers an argument to be no_log at the time that the 160 | # header is printed. If your environment doesn't have a problem securing 161 | # stdout from ansible-playbook (or you have manually specified no_log in your 162 | # playbook on all of the tasks where you have secret information) then you can 163 | # safely set this to True to get more informative messages. 164 | #display_args_to_stdout = False 165 | 166 | # by default (as of 1.3), Ansible will raise errors when attempting to dereference 167 | # Jinja2 variables that are not set in templates or action lines. Uncomment this line 168 | # to revert the behavior to pre-1.3. 169 | #error_on_undefined_vars = False 170 | 171 | # by default (as of 1.6), Ansible may display warnings based on the configuration of the 172 | # system running ansible itself. This may include warnings about 3rd party packages or 173 | # other conditions that should be resolved if possible. 174 | # to disable these warnings, set the following value to False: 175 | #system_warnings = True 176 | 177 | # by default (as of 1.4), Ansible may display deprecation warnings for language 178 | # features that should no longer be used and will be removed in future versions. 179 | # to disable these warnings, set the following value to False: 180 | #deprecation_warnings = True 181 | 182 | # (as of 1.8), Ansible can optionally warn when usage of the shell and 183 | # command module appear to be simplified by using a default Ansible module 184 | # instead. These warnings can be silenced by adjusting the following 185 | # setting or adding warn=yes or warn=no to the end of the command line 186 | # parameter string. This will for example suggest using the git module 187 | # instead of shelling out to the git command. 188 | # command_warnings = False 189 | 190 | 191 | # set plugin path directories here, separate with colons 192 | #action_plugins = /usr/share/ansible/plugins/action 193 | #cache_plugins = /usr/share/ansible/plugins/cache 194 | #callback_plugins = /usr/share/ansible/plugins/callback 195 | #connection_plugins = /usr/share/ansible/plugins/connection 196 | #lookup_plugins = /usr/share/ansible/plugins/lookup 197 | #inventory_plugins = /usr/share/ansible/plugins/inventory 198 | #vars_plugins = /usr/share/ansible/plugins/vars 199 | #filter_plugins = /usr/share/ansible/plugins/filter 200 | #test_plugins = /usr/share/ansible/plugins/test 201 | #terminal_plugins = /usr/share/ansible/plugins/terminal 202 | #strategy_plugins = /usr/share/ansible/plugins/strategy 203 | 204 | 205 | # by default, ansible will use the 'linear' strategy but you may want to try 206 | # another one 207 | #strategy = free 208 | 209 | # by default callbacks are not loaded for /bin/ansible, enable this if you 210 | # want, for example, a notification or logging callback to also apply to 211 | # /bin/ansible runs 212 | #bin_ansible_callbacks = False 213 | 214 | 215 | # don't like cows? that's unfortunate. 216 | # set to 1 if you don't want cowsay support or export ANSIBLE_NOCOWS=1 217 | #nocows = 1 218 | 219 | # set which cowsay stencil you'd like to use by default. When set to 'random', 220 | # a random stencil will be selected for each task. The selection will be filtered 221 | # against the `cow_whitelist` option below. 222 | #cow_selection = default 223 | #cow_selection = random 224 | 225 | # when using the 'random' option for cowsay, stencils will be restricted to this list. 226 | # it should be formatted as a comma-separated list with no spaces between names. 227 | # NOTE: line continuations here are for formatting purposes only, as the INI parser 228 | # in python does not support them. 229 | #cow_whitelist=bud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,\ 230 | # hellokitty,kitty,luke-koala,meow,milk,moofasa,moose,ren,sheep,small,stegosaurus,\ 231 | # stimpy,supermilker,three-eyes,turkey,turtle,tux,udder,vader-koala,vader,www 232 | 233 | # don't like colors either? 234 | # set to 1 if you don't want colors, or export ANSIBLE_NOCOLOR=1 235 | #nocolor = 1 236 | 237 | # if set to a persistent type (not 'memory', for example 'redis') fact values 238 | # from previous runs in Ansible will be stored. This may be useful when 239 | # wanting to use, for example, IP information from one group of servers 240 | # without having to talk to them in the same playbook run to get their 241 | # current IP information. 242 | #fact_caching = memory 243 | 244 | #This option tells Ansible where to cache facts. The value is plugin dependent. 245 | #For the jsonfile plugin, it should be a path to a local directory. 246 | #For the redis plugin, the value is a host:port:database triplet: fact_caching_connection = localhost:6379:0 247 | 248 | #fact_caching_connection=/tmp 249 | 250 | 251 | 252 | # retry files 253 | # When a playbook fails by default a .retry file will be created in ~/ 254 | # You can disable this feature by setting retry_files_enabled to False 255 | # and you can change the location of the files by setting retry_files_save_path 256 | 257 | #retry_files_enabled = False 258 | #retry_files_save_path = ~/.ansible-retry 259 | 260 | # squash actions 261 | # Ansible can optimise actions that call modules with list parameters 262 | # when looping. Instead of calling the module once per with_ item, the 263 | # module is called once with all items at once. Currently this only works 264 | # under limited circumstances, and only with parameters named 'name'. 265 | #squash_actions = apk,apt,dnf,homebrew,pacman,pkgng,yum,zypper 266 | 267 | # prevents logging of task data, off by default 268 | #no_log = False 269 | 270 | # prevents logging of tasks, but only on the targets, data is still logged on the master/controller 271 | #no_target_syslog = False 272 | 273 | # controls whether Ansible will raise an error or warning if a task has no 274 | # choice but to create world readable temporary files to execute a module on 275 | # the remote machine. This option is False by default for security. Users may 276 | # turn this on to have behaviour more like Ansible prior to 2.1.x. See 277 | # https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user 278 | # for more secure ways to fix this than enabling this option. 279 | #allow_world_readable_tmpfiles = False 280 | 281 | # controls the compression level of variables sent to 282 | # worker processes. At the default of 0, no compression 283 | # is used. This value must be an integer from 0 to 9. 284 | #var_compression_level = 9 285 | 286 | # controls what compression method is used for new-style ansible modules when 287 | # they are sent to the remote system. The compression types depend on having 288 | # support compiled into both the controller's python and the client's python. 289 | # The names should match with the python Zipfile compression types: 290 | # * ZIP_STORED (no compression. available everywhere) 291 | # * ZIP_DEFLATED (uses zlib, the default) 292 | # These values may be set per host via the ansible_module_compression inventory 293 | # variable 294 | #module_compression = 'ZIP_DEFLATED' 295 | 296 | # This controls the cutoff point (in bytes) on --diff for files 297 | # set to 0 for unlimited (RAM may suffer!). 298 | #max_diff_size = 1048576 299 | 300 | # This controls how ansible handles multiple --tags and --skip-tags arguments 301 | # on the CLI. If this is True then multiple arguments are merged together. If 302 | # it is False, then the last specified argument is used and the others are ignored. 303 | # This option will be removed in 2.8. 304 | #merge_multiple_cli_flags = True 305 | 306 | # Controls showing custom stats at the end, off by default 307 | #show_custom_stats = True 308 | 309 | # Controls which files to ignore when using a directory as inventory with 310 | # possibly multiple sources (both static and dynamic) 311 | #inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo 312 | 313 | # This family of modules use an alternative execution path optimized for network appliances 314 | # only update this setting if you know how this works, otherwise it can break module execution 315 | #network_group_modules=eos, nxos, ios, iosxr, junos, vyos 316 | 317 | # When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as 318 | # a loop with `with_foo`) to return data that is not marked "unsafe". This means the data may contain 319 | # jinja2 templating language which will be run through the templating engine. 320 | # ENABLING THIS COULD BE A SECURITY RISK 321 | #allow_unsafe_lookups = False 322 | 323 | # set default errors for all plays 324 | #any_errors_fatal = False 325 | 326 | [inventory] 327 | # enable inventory plugins, default: 'host_list', 'script', 'yaml', 'ini', 'auto' 328 | #enable_plugins = host_list, virtualbox, yaml, constructed 329 | 330 | # ignore these extensions when parsing a directory as inventory source 331 | #ignore_extensions = .pyc, .pyo, .swp, .bak, ~, .rpm, .md, .txt, ~, .orig, .ini, .cfg, .retry 332 | 333 | # ignore files matching these patterns when parsing a directory as inventory source 334 | #ignore_patterns= 335 | 336 | # If 'true' unparsed inventory sources become fatal errors, they are warnings otherwise. 337 | #unparsed_is_failed=False 338 | 339 | [privilege_escalation] 340 | #become=True 341 | #become_method=sudo 342 | #become_user=root 343 | #become_ask_pass=False 344 | 345 | [paramiko_connection] 346 | 347 | # uncomment this line to cause the paramiko connection plugin to not record new host 348 | # keys encountered. Increases performance on new host additions. Setting works independently of the 349 | # host key checking setting above. 350 | #record_host_keys=False 351 | 352 | # by default, Ansible requests a pseudo-terminal for commands executed under sudo. Uncomment this 353 | # line to disable this behaviour. 354 | #pty=False 355 | 356 | # paramiko will default to looking for SSH keys initially when trying to 357 | # authenticate to remote devices. This is a problem for some network devices 358 | # that close the connection after a key failure. Uncomment this line to 359 | # disable the Paramiko look for keys function 360 | #look_for_keys = False 361 | 362 | # When using persistent connections with Paramiko, the connection runs in a 363 | # background process. If the host doesn't already have a valid SSH key, by 364 | # default Ansible will prompt to add the host key. This will cause connections 365 | # running in background processes to fail. Uncomment this line to have 366 | # Paramiko automatically add host keys. 367 | #host_key_auto_add = True 368 | 369 | [ssh_connection] 370 | 371 | # ssh arguments to use 372 | # Leaving off ControlPersist will result in poor performance, so use 373 | # paramiko on older platforms rather than removing it, -C controls compression use 374 | #ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s 375 | 376 | # The base directory for the ControlPath sockets. 377 | # This is the "%(directory)s" in the control_path option 378 | # 379 | # Example: 380 | # control_path_dir = /tmp/.ansible/cp 381 | #control_path_dir = ~/.ansible/cp 382 | 383 | # The path to use for the ControlPath sockets. This defaults to a hashed string of the hostname, 384 | # port and username (empty string in the config). The hash mitigates a common problem users 385 | # found with long hostames and the conventional %(directory)s/ansible-ssh-%%h-%%p-%%r format. 386 | # In those cases, a "too long for Unix domain socket" ssh error would occur. 387 | # 388 | # Example: 389 | # control_path = %(directory)s/%%h-%%r 390 | #control_path = 391 | 392 | # Enabling pipelining reduces the number of SSH operations required to 393 | # execute a module on the remote server. This can result in a significant 394 | # performance improvement when enabled, however when using "sudo:" you must 395 | # first disable 'requiretty' in /etc/sudoers 396 | # 397 | # By default, this option is disabled to preserve compatibility with 398 | # sudoers configurations that have requiretty (the default on many distros). 399 | # 400 | #pipelining = False 401 | 402 | # Control the mechanism for transferring files (old) 403 | # * smart = try sftp and then try scp [default] 404 | # * True = use scp only 405 | # * False = use sftp only 406 | #scp_if_ssh = smart 407 | 408 | # Control the mechanism for transferring files (new) 409 | # If set, this will override the scp_if_ssh option 410 | # * sftp = use sftp to transfer files 411 | # * scp = use scp to transfer files 412 | # * piped = use 'dd' over SSH to transfer files 413 | # * smart = try sftp, scp, and piped, in that order [default] 414 | #transfer_method = smart 415 | 416 | # if False, sftp will not use batch mode to transfer files. This may cause some 417 | # types of file transfer failures impossible to catch however, and should 418 | # only be disabled if your sftp version has problems with batch mode 419 | #sftp_batch_mode = False 420 | 421 | # The -tt argument is passed to ssh when pipelining is not enabled because sudo 422 | # requires a tty by default. 423 | #use_tty = True 424 | 425 | # Number of times to retry an SSH connection to a host, in case of UNREACHABLE. 426 | # For each retry attempt, there is an exponential backoff, 427 | # so after the first attempt there is 1s wait, then 2s, 4s etc. up to 30s (max). 428 | #retries = 3 429 | 430 | [persistent_connection] 431 | 432 | # Configures the persistent connection timeout value in seconds. This value is 433 | # how long the persistent connection will remain idle before it is destroyed. 434 | # If the connection doesn't receive a request before the timeout value 435 | # expires, the connection is shutdown. The default value is 30 seconds. 436 | #connect_timeout = 30 437 | 438 | # Configures the persistent connection retry timeout. This value configures the 439 | # the retry timeout that ansible-connection will wait to connect 440 | # to the local domain socket. This value must be larger than the 441 | # ssh timeout (timeout) and less than persistent connection idle timeout (connect_timeout). 442 | # The default value is 15 seconds. 443 | #connect_retry_timeout = 15 444 | 445 | # The command timeout value defines the amount of time to wait for a command 446 | # or RPC call before timing out. The value for the command timeout must 447 | # be less than the value of the persistent connection idle timeout (connect_timeout) 448 | # The default value is 10 second. 449 | #command_timeout = 10 450 | 451 | [accelerate] 452 | #accelerate_port = 5099 453 | #accelerate_timeout = 30 454 | #accelerate_connect_timeout = 5.0 455 | 456 | # The daemon timeout is measured in minutes. This time is measured 457 | # from the last activity to the accelerate daemon. 458 | #accelerate_daemon_timeout = 30 459 | 460 | # If set to yes, accelerate_multi_key will allow multiple 461 | # private keys to be uploaded to it, though each user must 462 | # have access to the system via SSH to add a new key. The default 463 | # is "no". 464 | #accelerate_multi_key = yes 465 | 466 | [selinux] 467 | # file systems that require special treatment when dealing with security context 468 | # the default behaviour that copies the existing context or uses the user default 469 | # needs to be changed to use the file system dependent context. 470 | #special_context_filesystems=nfs,vboxsf,fuse,ramfs,9p 471 | 472 | # Set this to yes to allow libvirt_lxc connections to work without SELinux. 473 | #libvirt_lxc_noseclabel = yes 474 | 475 | [colors] 476 | #highlight = white 477 | #verbose = blue 478 | #warn = bright purple 479 | #error = red 480 | #debug = dark gray 481 | #deprecate = purple 482 | #skip = cyan 483 | #unreachable = red 484 | #ok = green 485 | #changed = yellow 486 | #diff_add = green 487 | #diff_remove = red 488 | #diff_lines = cyan 489 | 490 | 491 | [diff] 492 | # Always print diff when running ( same as always running with -D/--diff ) 493 | # always = no 494 | 495 | # Set how many context lines to show in diff 496 | # context = 3 497 | --------------------------------------------------------------------------------