Provisioning IOS-XE Interfaces with Ansible

"The What?" - In this blog I want to cover an example of using Ansible to automate the process of provisioning ports based on user defined variables & ansible facts across different ios-xe platform types.

"The Why?" - My drive for this is due to a Software-Defined Access (SDA) environment where DNAC automagically provisions interfaces, dot1x timers, among other items that could impact pxe booting from an imaging perspective.

"The How?" - The meat and potatoes for this is basically a few main parts:

  • Knowing what needs to be changed to meet your environment needs in regard to timers/onboarding for imaging

  • Knowing environment platform/interface types

Now I will breakdown the actual ansible playbook piece by piece so that we understand how the magic works. In the first snippet it is important to realize that I have gather_facts set to True. Setting this to true will allow ansible to collect information about the remote host (swtich) at the start of execution. Information collected can then be referenced in your code as variables, etc. In this case I had to figure out a way to set a variable to declare interface type. Reason being is because different platforms come with different interface types (int g1/0/1; int te1/0/1; etc.). So using gather_facts I was able to find a collected variable known as 'net_model' which allowed me to identify platform type as well as the other key identifier (interface type).

Moving to the tasks section I configured several conditionals. Quick note, conditionals allow you to do many things. In this case they allowed me to declare variables based on the value of the ansible facts 'net_model' variables collected when gathering facts. Within each conditional shown below you see set_fact, which allows us to store a variable on the fly to reference later in following plays. intf is the variable name which is the interface type I will need to use in further plays which is based on the platform the admin is attempting to connect to. Once ansible determines a match on one of the conditionals the playbook continues (described further down)

Quick note: The switch IP address and interface number is collected via user variables using a tower survey that prompts the user who is running the job template at launch, which looks like this inside tower:

First sections of playbook:

Now that the platform type has been identified via the conditionals based on fact gathering the remaining plays do the configuration part using the variables given to us from the user & the on-the-fly variable from the conditional.

In the play 'Deploy configurations to devices' I push config from a static configuration file on tower using the ios_config module. This module essentially allows us to work with the switch configuration. Note that save_when tells the device to save running-config to startup when the configuration has been modified via ansible.

The last play 'Deploy configurations to devices' uses the same ios_config module. The 'lines' section is an ordered set of commands that will get configured in the section. 'parents' is the key component here that pieces together our variables to ensure that we properly provision the interface that we desire to tweak config on. This parents key identifies what interface we wish to work on. Notice in this section key that the intf, variable determined from conditionals shown earlier, declares interface type & the {{ port }} variable specifies the user interface number variable collected at template launch.

The result inside tower from a successful template job looks like the following example showing us proof that the switch interface config is updated:

Further verification can be conducted via logging directly into the switch that you just automated interface provisioning against.

Pretty cool stuff. Hopefully this example sheds some light for those looking to automate some mundane tasks.

Lastly, just sharing this because it took me some time to figure out and this may come in handy for those with similar platforms and configurations. In my inventory that is used with the job template to connect to a switch I had to do several things from a variable perspective to ensure I could successfully connect and allow users to dynamically select/configure switches. First part is the easy part, {{ ip_addr }} variable. This allows me to gather the switch ip address that the admin wishes to connect to using the user survey as described earlier. That looks like this in inventory:

ansible_host: "{{ ip_addr }}"

The second/last gotcha variables I defined to ensure connectivity was good between ansible and ios-xe platform since I was having headaches. These variables are pretty much self explainable, but ansible has really good documentation if needed. Note that these can change across environments so best bet is to test connectivity via trial/error:

ansible_ssh_common_args: "-o HostKeyAlgorithms=ssh-rsa -o KexAlgorithms=diffie-hellman-group14-sha1 -o Ciphers=aes256-ctr -o MACs=hmac-sha2-256,hmac-sha2-512"
ansible_connection: network_cli
ansible_become: yes
ansible_network_os: ios
buffer_read_timeout: 10

That wraps this ansible automation with Cisco ios-xe platforms up. I hope this example is helpful. Cheers!


Recent Posts

See All

"The What?" - In this blog I want to cover a project with Ansible that I created to automate parts of a workflow relating to an SDA edge node (EN) deployment. Now to breakdown the workflow I will be

"The What?" - In this blog I want to cover a brief overview of one way to install AnyConnect (AC) on a linux client running a supported OS. Once I cover the overview I intend on covering a few Ansibl