Network Automation – Ansible Learnings – Week 4 – Configuring Multiple Loopbacks
This week has been a very busy week as I am sure it is for most of you coming into this time of the year. However I have managed to figure out how I can deploy unique IP addressed loopbacks across my cisco virtual routers. Working out how to achieve this has been great in that I have had to learn more how to leverage jinja2 templates, albeit in a very simple way.
I am still very new at how jinja2 templates can be leveraged within Ansible and playbooks, but the capabilities there look awesome and I am looking forward to exploring it further over the coming weeks. My next blog or two will be exploring this to some extent as I look to how I can leverage it to create interfaces and then VRFs so I can work toward my project goal.
So this is what I have worked on this week. I have done research from multiple sources but the most helpful document actually came from what I assume is powerpoint notes from an Ansible course led by Red Hat.
https://ansible.github.io/workshops/decks/ansible_network.pdf
Preface: Ansible Host & Config file purposefully not included in this post. Also a commit command was not put in place for this lab playbook, but if you copy from this I encourage to add this in.
create_loopbacks_04.yml
--- - name: configure network devices hosts: nvnetlab1_routers gather_facts: false tasks: #Get the current router interfaces - name: Obtain current router interfaces cli_command: command: show ip int br register: current_ip_int_br - name: Display the current IP Interfaces debug: msg: "{{ current_ip_int_br.stdout }}" #Configure Loopbacks with Jinja2 Template - name: configure device with config cli_config: config: "{{ lookup('template', 'template.j2') }}" #Let handlers do the final actions notify: - PRINT UPDATED CONFIGURATION #Show the updated interface information as a way of confirming the playbook has worked - name: Obtain updated IP address configuration cli_command: command: show ip int br register: updated_ip_int_br handlers: - name: PRINT UPDATED CONFIGURATION debug: msg: "{{ updated_ip_int_br.stdout }}"
Jinja2 Template
{% for interface,ip in iosxe[inventory_hostname].items() %} interface {{interface}} ip address {{ip}} 255.255.255.255 {% endfor %}
all.yml
Which is located in my /group_vars folder as a reference to the jinja2 template.
nvnetlab1_routers: NV-NET-LAB1-R1: loopback30: "10.111.30.1" NV-NET-LAB1-R2: loopback30: "10.111.30.2" NV-NET-LAB1-R3: loopback30: "10.111.30.3" NV-NET-LAB1-R4: loopback30: "10.111.30.4"
Running this produced the following output (output is badly formatted – apologies!)
(venv) Daniels-MacBook-Pro:intro-ansible daniel$ ansible-playbook create_loopbacks_04.yml
PLAY [configure network devices] *******************************************************************************************************************************************************************************************************
TASK [Obtain current router interfaces] ************************************************************************************************************************************************************************************************
ok: [NV-NET-LAB1-R4]
ok: [NV-NET-LAB1-R3]
ok: [NV-NET-LAB1-R1]
ok: [NV-NET-LAB1-R2]
TASK [Display the current IP Interfaces] ***********************************************************************************************************************************************************************************************
ok: [NV-NET-LAB1-R1] =>
msg: |-
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 192.168.2.2 YES NVRAM up up
GigabitEthernet2 unassigned YES manual up up
GigabitEthernet2.201 192.168.2.10 YES manual up up
GigabitEthernet2.210 unassigned YES manual deleted down
GigabitEthernet3 unassigned YES NVRAM administratively down down
GigabitEthernet4 unassigned YES unset administratively down down
Loopback1 192.168.255.20 YES NVRAM up up
Loopback3 unassigned YES manual up up
ok: [NV-NET-LAB1-R2] =>
msg: |-
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 192.168.2.3 YES manual up up
GigabitEthernet2 unassigned YES manual up up
GigabitEthernet2.201 192.168.2.11 YES manual up up
GigabitEthernet2.210 unassigned YES manual deleted down
GigabitEthernet3 unassigned YES NVRAM administratively down down
GigabitEthernet4 unassigned YES unset administratively down down
Loopback1 192.168.255.21 YES manual up up
ok: [NV-NET-LAB1-R3] =>
msg: |-
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 192.168.2.4 YES manual up up
GigabitEthernet2 unassigned YES NVRAM administratively down down
GigabitEthernet3 unassigned YES NVRAM administratively down down
Loopback1 192.168.255.23 YES manual up up
ok: [NV-NET-LAB1-R4] =>
msg: |-
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 192.168.2.5 YES manual up up
GigabitEthernet2 unassigned YES NVRAM administratively down down
GigabitEthernet3 unassigned YES NVRAM administratively down down
Loopback1 192.168.255.24 YES manual up up
TASK [configure device with config] ****************************************************************************************************************************************************************************************************
changed: [NV-NET-LAB1-R3]
changed: [NV-NET-LAB1-R2]
changed: [NV-NET-LAB1-R1]
changed: [NV-NET-LAB1-R4]
TASK [Obtain updated IP address configuration] *****************************************************************************************************************************************************************************************
ok: [NV-NET-LAB1-R1]
ok: [NV-NET-LAB1-R3]
ok: [NV-NET-LAB1-R2]
ok: [NV-NET-LAB1-R4]
RUNNING HANDLER [PRINT UPDATED CONFIGURATION] ******************************************************************************************************************************************************************************************
ok: [NV-NET-LAB1-R3] =>
msg: |-
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 192.168.2.4 YES manual up up
GigabitEthernet2 unassigned YES NVRAM administratively down down
GigabitEthernet3 unassigned YES NVRAM administratively down down
Loopback1 192.168.255.23 YES manual up up
Loopback30 10.111.30.3 YES manual up up
ok: [NV-NET-LAB1-R2] =>
msg: |-
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 192.168.2.3 YES manual up up
GigabitEthernet2 unassigned YES manual up up
GigabitEthernet2.201 192.168.2.11 YES manual up up
GigabitEthernet2.210 unassigned YES manual deleted down
GigabitEthernet3 unassigned YES NVRAM administratively down down
GigabitEthernet4 unassigned YES unset administratively down down
Loopback1 192.168.255.21 YES manual up up
Loopback30 10.111.30.2 YES manual up up
ok: [NV-NET-LAB1-R1] =>
msg: |-
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 192.168.2.2 YES NVRAM up up
GigabitEthernet2 unassigned YES manual up up
GigabitEthernet2.201 192.168.2.10 YES manual up up
GigabitEthernet2.210 unassigned YES manual deleted down
GigabitEthernet3 unassigned YES NVRAM administratively down down
GigabitEthernet4 unassigned YES unset administratively down down
Loopback1 192.168.255.20 YES NVRAM up up
Loopback3 unassigned YES manual up up
Loopback30 10.111.30.1 YES manual up up
ok: [NV-NET-LAB1-R4] =>
msg: |-
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 192.168.2.5 YES manual up up
GigabitEthernet2 unassigned YES NVRAM administratively down down
GigabitEthernet3 unassigned YES NVRAM administratively down down
Loopback1 192.168.255.24 YES manual up up
Loopback30 10.111.30.4 YES manual up up
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
NV-NET-LAB1-R1 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
NV-NET-LAB1-R2 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
NV-NET-LAB1-R3 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
NV-NET-LAB1-R4 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
This produced the following results on my lab routers.
NV-NET-LAB1-R1
NV-NET-LAB1-R1#SH IP INT BR Interface IP-Address OK? Method Status Protocol GigabitEthernet1 192.168.2.2 YES manual up GigabitEthernet2 unassigned YES manual up GigabitEthernet3 unassigned YES NVRAM administratively GigabitEthernet4 unassigned YES unset administratively Loopback1 192.168.255.21 YES manual up Loopback30 10.111.30.1 YES manual up
NV-NET-LAB1-R2
NV-NET-LAB1-R2#SH IP INT BR Interface IP-Address OK? Method Status Protocol GigabitEthernet1 192.168.2.3 YES manual up GigabitEthernet2 unassigned YES manual up GigabitEthernet3 unassigned YES NVRAM administratively GigabitEthernet4 unassigned YES unset administratively Loopback1 192.168.255.22 YES manual up Loopback30 10.111.30.2 YES manual up
NV-NET-LAB1-R3
NV-NET-LAB1-R3#SH IP INT BR Interface IP-Address OK? Method Status Protocol GigabitEthernet1 192.168.2.4 YES manual up GigabitEthernet2 unassigned YES manual up GigabitEthernet3 unassigned YES NVRAM administratively GigabitEthernet4 unassigned YES unset administratively Loopback1 192.168.255.23 YES manual up Loopback30 10.111.30.3 YES manual up
NV-NET-LAB1-R4
NV-NET-LAB1-R4#SH IP INT BR Interface IP-Address OK? Method Status Protocol GigabitEthernet1 192.168.2.5 YES manual up GigabitEthernet2 unassigned YES manual up GigabitEthernet3 unassigned YES NVRAM administratively GigabitEthernet4 unassigned YES unset administratively Loopback1 192.168.255.24 YES manual up Loopback30 10.111.30.4 YES manual up
Great stuff right?
Well yeah absolutely job achieved, however there are two things I don’t like about this or at least where I know I can immediately improve upon it.
- Playbook and the jinja2 template pull from a static yml file, this needs to be a file that is either automatically generated based on a predefined subnet block for loopbacks, or pulled from a csv or some centrally governed list of predefined allocated ipaddresses. The reason for this would be for portability and compliance of network policy. I will learn how to achieve this over the next few weeks I imagine.
- Every time the playbook is run it records it as a change rather than seeing the interfaces and Ip addrresses already there. I believe this is to do with the cli_config module in how it works. I will in time understand this better but for now I will keep it back of mind. I should note that if you were to use a non-agnostic module such as ios_l3_interface and input the details there in a more static way, Ansible can detect if a change was actually made.
Anyway I have enjoyed the learnings this week in Ansible, and I as I said, I am looking forward to leveraging jinja2 templates within my playbooks moving forward so expect the next post be to about some simple jinja2 templating usage.
Of course, please feel comment and let me know if there is anything I missed here or I could do better with the playbook (including links to examples where people have done it better). Always keen to learn and find out more!
Have a great rest of your week everyone and Merry Christmas!
Recent Comments