Skip to content

Project 1 – Ansible – Deploy New Network & Network Security – Stage 3 – Deploy VLANs to Cisco NX-OS Core Switch

Moving on from the success of the previous playbook, I now needed to deploy changes onto the 1 NXOS 9k virtual switch. The changes that will be deployed here will help you to see and give shape to the network that I am building for my hosts in this made up LAB1 network.

With this playbook, again I have kept the idea that it needs pre-flight checks, and post verification checks to confirm for me that everything I am doing isn’t going to break something and what I have deployed is actually working as expected. I have also synthetically injected in mistakes to see how my playbook handles errors that over my brief time of being a network engineer I have encountered either through mistakes of my own or others. This playbook is a good one to use where your environment is not greenfields and you are working in environments where changes can be made where they different follow the standard operating procedure or change manage – “whoa, shock and horror, that would never happen right…”

Yep it does…


Stage 3 Playbook Breakdown


Task Groupings…

So anyway going over the playbook. I decided to use 3 types of tasks that Ansible has, if you were not aware there are 3 types of task groupings, these as per their name suggest an order to the execution of their tasks – pre_tasks, tasks, post_tasks.

I like setting out the playbooks so far in this way, and there are probably cases where this not required but it allows me to have some organisation in my playbook. It also allows me to also have organisation in my IDE tool – PyCharm CE. I am sure Visual Code doesn’t in the same way, so keep using whatever is comfortable to you. But anyway this is what the separation of task because of indentation that is used and how PyCharm knows how to display it.

As you should be able to see when you click on the image, I can expand out each task groupings and work on them as needed. For me and how my brain works, I find this quite handy, I understand that this may not really mean much to others and therefore there are much more reasonable reasons to use the different task groupings, but I like it this way. Also there is a logical flow of tasks following this method as I consider changes to have 3 essential phases, but I am sure there are a million and one articles on how a change process should work so lets not get into those semantics here.

Vendor Ansible specific module, not an agnostic module?

The next thing you might notice, I have used predominately nxos_<mod-command> throughout this playbook, when in the previous playbook I was a bit of a mix of agnostic and vendor specific. There isn’t a super great argument here, actually all of it was with the agnostic commands before, and if you are in an environment with disparate devices then Ansible is correct in building playbooks with an agnostic approach is much better. I would have done this, but I wanted to use the nxos module because I hadn’t really been using it and thought I would get familiar with it.

Ansible item loops and not all in a jinja2 template?

Yep, I could have and I should have, but ultimately to move the project on and achieve my goal I put it on hold and am going to stew on it and play with it over the week or 2 and  then potentially do a separate post where all the configuration changes here are templated in a much nicer way.

Playbook time!


 # Playbook Title: project1_stage2_deploy_coreswitc_vlans.yml
 # Version: 1.1
 # Playbook created by Daniel Bostock
 # Contact me, with ideas to improve or to simply discuss - [email protected]
 # MIT License
 # Feel free to re-use, I obviously take no responsibility for where and how you use it.
 - name: Project 1 - Stage 3 - Deploy VLANs Interfaces & VLANs
 # Define the target hosts here
   hosts: nvnetlab1_switches_nxos
   gather_facts: no
 # Define the VLAN ID's
 # --- Begin the pre-flight checks - backup, obtain current interface configuration, current running configurations ---
 # IF this is a new network device deployment these pre_tasks checks will often be unecessary and I recommend commenting or removing them.
 # Check if there are no current outstanding and not committed configuration changes
     - pause:
        seconds: 2
        prompt: "Pre-flight checklists for deployment are beginning. This first step is checking if there are outstanding changes on the target device."
     - name: Compare the current Startup vs Running configuration to confirm no outstanding changes
           diff_against: intended
           intended_config: "{{ lookup('file', '~/Google Drive/Ansible/Lab03-Network/pre_dep_backups/pre_dep_startup/{{ inventory_hostname }}_pre_dep_startup.cfg') }}"
     - pause:
        prompt: "Press enter to continue if there are no outstanding changes. If there are; proceed with caution and awareness, as this playbook will deploy these changes as well."
 # Begin backup, modify backup directory as required
     - name: Backup of the current running config before deploying changes to the device
         backup: yes
           dir_path: ~/Google Drive/Ansible/Lab03-Network/pre_dep_backups/pre_dep_running/
         host: "{{ inventory_hostname }}"
 # Obtain and Display to the deployer what the current configuration is
     - name: Obtain list of configured L3 interefaces on the device
           commands: sh ip int br
       register: current_target_int_conf
     - name: Display the list of configured L3 interfaces on the device
         msg: "{{ current_target_int_conf.stdout }}"
 # Obtain and Display new configuration to the deployer what they will be deploying
     - name: Display the conversion change that will take a L2 switch interface to a L3 switch interface
         msg: "{{ lookup('template', 'project1_stage3_cs1_int-conf_template.j2') }}"
     - pause:
         prompt: "Confirm that the target interface(s) and new configuration is correct. Press enter to proceed, or Control+C to cancel."
 # --- Begin the deployment of the changes ---
     - name: Modify the target device L2 switch interface to a L3 switch interface
            lines: "{{ lookup('template', 'project1_stage3_cs1_int-conf_template.j2') }}"
     - name: Deploy VLAN IDs
           - vlan_id: "{{ item.vlan_id }}"
             name: "{{ }}"
          - { vlan_id: 10, name: LAB1-SRV-VLAN10 }
          - { vlan_id: 11, name: LAB1-DMZ-VLAN11 }
          - { vlan_id: 12, name: LAB1-DKR-VLAN12 }
     - name: Configure Switch Ports to be access ports for the respective VLANs
             - name: "{{ }}"
                 vlan: "{{ item.vlan }}"
           - { name: Ethernet1/2, vlan: 10 }
           - { name: Ethernet1/3, vlan: 11 }
           - { name: Ethernet1/4, vlan: 12 }
 #Give time for the enable of interfaces to take effect
     - pause:
         seconds: 30
         prompt: Waiting for interfaces to come up...
 # --- Begin Post Verification Testing to configuration deployed as expected ---
 #Obtain the information to display to the deployer with the handlers the configuration deployed
     - name: Obtain updated IP address configuration
         commands: show ip int br | i Vlan
       register: updated_ip_int
     - name: Show the updated IP address configuration
         msg: "{{ updated_ip_int.stdout }}"
     - name: Obtain NEW running configuation on the deployed device interfaces
            - show run int {{ LAB1_SERVER_VLAN }}
            - show run int {{ LAB1_DMZ_VLAN }}
            - show run int {{ LAB1_DOCKER_VLAN }}
       register: deployed_targl3int_runconf
     - name: Display NEW running configuration on interface
         msg: "{{ deployed_targl3int_runconf.stdout }}"
 # Ping to test L3 Connectivity
     - name: Test reachability to Edge Gateway using newly created vlan interfaces
            source: "{{ item.source }}"
         - { source: }
         - { source: }
         - { source: }
         - { source: }
       register: deployed_vlanip_ping_results
       ignore_errors: yes
     - name: Show the Ping Results
         msg: "{{ deployed_vlanip_ping_results }}"
     - pause:
         prompt: "Review configuration & Connectivity Test Report, if configuration deployed is correct and no issues, press enter to commit to memory or ctrl-c to leave in running config."
 #Now deployment is complete the configuration will be written to the memory (startup config)
     - name: Save the deployed configuration (running config) to the memory (startup config).
           save_when: modified



{% for interface,ip in nvnetlab1_switches_nxos[inventory_hostname].items() %}<br>
interface {{ interface }}
ip address {{ip}}
ip router ospf 1 area
description LAB1-SRV-VLAN{{ interface }}
no shut
{% endfor %}


interface ethernet 1/1
no switchport
ip address
ip router ospf 1 area
no shut

Group Vars files

Portion of all.yml file which relates to this playbook

      VLAN10: ""
      VLAN11: ""
      VLAN12: ""

Playbook in action!

Final Thoughts

Cool, another win! The base connectivity is now there and is working. The next stage is deploy some level of security. ACL’s will give us a very low level security posture. Automating security into our change automation is a great thing to think of and to be honest if we aren’t doing this even at basic level in the form of ACL’s then we are taking away an awesome function of network automation. I am looking forward to this next stage and stage 5 where I get to apply some base line security practices and do it quickly and easy.

Another thing to note, whilst I have been writing this playbook I had also been considering how I tie all the playbooks together as mentioned in the initial project post. To keep it simple, I am going to use what is called a master playbook. This essentially will be a orchestration playbook.

Now is this the best way to do this? Probably not, but I know it will get the job done. As always I will keep working to get the project done and then later projects will build upon this one and leverage more of the built in power of Ansible. I already have some ideas how to improve things here. I am however keeping my eyes firmly on the prize here because often in the past I have gotten side tracked by something new and shiny and not finished what I started. I have come to the opinion over the last few months when it comes to learning, just get it done and get it done in the best possible way I know in the moment and then improve, that is after all learning.

Now I will give you a brief glimpse into the orchestration playbook that I have written and then it in action below. This is just stage 2 and 3, as I build each new stage, I tear it all down what I have done and then rebuild it with this orchestration tool to see how it all works together in one big deployment playbook.

As always please feel free to leave any comments, questions, ideas, criticisms – I don’t mind really! If you are someone who knows me, I don’t mind criticism and often I incite it… Haha!

Leave a Reply

Skip to toolbar