- name: Fetch passwords set_fact: password: '{{ lookup("passwordstore", "switch/"~inventory_hostname, returnall=true, missing="empty") | from_yaml }}' - name: Set username and password for ansible connection set_fact: ansible_ssh_user: '{{ password.user }}' ansible_ssh_pass: '{{ password.pass }}' - name: Generate SNMP engine ID from serial number set_fact: snmp_engine_id: '{{ (serial | sha1)[:24] }}' - name: Get switch facts cisco.ios.ios_facts: gather_subset: config # Determine VLANs to add and remove from switch. - set_fact: actual_vlans: "{{ vlans | map(attribute='vid') }}" switch_vlans: "{{ ansible_net_config | split('\n') | select('match', '^ *vlan (range )?[0-9]') | map('regex_search', '[0-9,-]+') | join(',') | ansible.netcommon.vlan_expander }}" - set_fact: add_vlans: "{{ actual_vlans | difference(switch_vlans) }}" del_vlans: "{{ switch_vlans | difference(actual_vlans) }}" - name: Set configuration ansible.netcommon.cli_config: config: '{{ lookup("template", "config-"~manufacturer~"-"~device_type~".j2") }}' vars: ansible_command_timeout: 240 ansible_terminal_stderr_re: [] # some errors are not actually errors register: result # These lines are not displayed by 'sho ru' and always reported as different, so ignore them. changed_when: result.commands | reject('match', '^(no shutdown|no switchport access vlan|no switchport trunk native vlan|no voice vlan.*|switchport mode access|switchport mode hybrid|interface .*|no enable service web-server https?|no ip dhcp snooping|no ip dhcp snooping trust|no switchport port-security.*)$') notify: write config - name: Run model-specific tasks include_tasks: '{{ manufacturer~"-"~device_type~".yml" }}'